Go でポインター レシーバー メソッドを使用してインターフェイスに値レシーバーを割り当てることができないのはなぜですか?

Linda Hamilton
リリース: 2024-11-24 04:15:20
オリジナル
560 人が閲覧しました

Why Can't I Assign a Value Receiver to an Interface with Pointer Receiver Methods in Go?

Go インターフェイス実装のレシーバー タイプを理解する

Go では、メソッドはいずれかの値レシーバー (func (t T) m()) を持つことができます。または、構造体型のポインター レシーバー (func (t *T) m())。レシーバーのタイプによって、メソッドを呼び出すときに使用する値が決まります。

次のコードを考えてみましょう:

import "fmt"

type greeter interface {
    hello()
    goodbye()
}

type tourGuide struct {
    name string
}

func (t tourGuide) hello() {
    fmt.Println("Hello", t.name)
}

func (t *tourGuide) goodbye() {
    fmt.Println("Goodbye", t.name)
}

func main() {
    var t1 tourGuide = tourGuide{"James"}
    t1.hello() // Hello James
    t1.goodbye() // Goodbye James (same as (&t1).goodbye())

    var t2 *tourGuide = &tourGuide{"Smith"}
    t2.hello() // Hello Smith
    t2.goodbye() // Goodbye Smith (same as (*t2).hello())

    // illegal: t1 is not assignable to g1 (why?)
    // var g1 greeter = t1

    var g2 greeter = t2
    g2.hello() // Hello Smith
    g2.goodbye() // Goodbye Smith
}
ログイン後にコピー

なぜ変数 t1 のいずれかを使用して TourGuide のメソッドを呼び出すことができるのか不思議に思うかもしれません。 TourGuide 型のポインタ、または *tourGuide 型のポインタ t2 ですが、t1 を型のインターフェイス変数 g1 に割り当てることはできませんgreeter.

その理由は、インターフェイス メソッドの受信側の型にあります。この場合、hello と Goodbye の両方にポインタ レシーバがあります。そのため、レシーバー値として使用できるのはポインター値のみです。

t1.hello() および t1.goodbye() を呼び出すと、コンパイラーは自動的に t1 のアドレスを取得し、それをレシーバーとして使用します。 t1 はアドレス指定可能な値であるためです。

ただし、t1 を g1 に代入しようとすると、コンパイラは t1 がアドレス可能な値ではないことを認識します。ポインタ値ですが、tourGuide 型の値です。インターフェイスはアドレス指定できないため、コンパイラは t1 のアドレスを取得して g1 に割り当てることができません。

要約すると、ポインタ レシーバはメソッドを呼び出すためにポインタ値を必要としますが、値レシーバはいずれかの値で呼び出すことができます。またはポインタ。ポインター レシーバー メソッドを使用してインターフェイスを実装する場合、インターフェイスに割り当てることができるのはポインター値のみです。

以上がGo でポインター レシーバー メソッドを使用してインターフェイスに値レシーバーを割り当てることができないのはなぜですか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

ソース:php.cn
このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。
著者別の最新記事
人気のチュートリアル
詳細>
最新のダウンロード
詳細>
ウェブエフェクト
公式サイト
サイト素材
フロントエンドテンプレート