なぜ Go 構造体変数はポインタ レシーバを備えたインターフェイスを実装できないのですか?
Go では、構造体メソッドはどちらかの値レシーバ (動作する) を持つことができます。構造体の値を直接操作する)、またはポインター レシーバー (構造体へのポインターを操作する)。インターフェイスを実装する場合、インターフェイス メソッドの受信側の型に応じて、どの型がインターフェイスを満たすことができるかについて微妙な制限があります。
次のコードを考慮してください。
type greeter interface { hello() goodbye() } type tourGuide struct { name string }
次のコードを使用してメソッドを定義できます。 TourGuide の値とポインターの両方のレシーバー:
func (t tourGuide) hello() { fmt.Println("Hello", t.name) } func (t *tourGuide) goodbye() { fmt.Println("Goodbye", t.name) }
さて、ここにキーがあります違い:
tourGuide の変数またはコピーは、値とポインターの両方のレシーバー メソッドを呼び出すことができます:
var t1 tourGuide = tourGuide{"James"} t1.hello() // works t1.goodbye() // works
ただし、インターフェイス変数は、インターフェイスと同じレシーバー型を持つすべてのインターフェイス メソッドを実装できる型から割り当てられます。それ自体:
var g2 greeter = &t2 // works because *tourGuide implements greeter's pointer receiver methods // illegal: t1 is not assignable to g1 // var g1 greeter = t1 // error: cannot use tourGuide as type greeter in assignment because tourGuide does not implement greeter (hello method has value receiver)
では、なぜ t1 はグリーター インターフェイスを実装できないのでしょうか?
その理由は、グリーター インターフェイスの hello() メソッドにポインター レシーバー。レシーバーとして TourGuide 値へのポインターを期待することを意味します。ただし、t1 は変数です (ポインタではありません)。値変数はアドレス指定可能ですが、インターフェイス値は参照ではなく、保存された値のコピーを保持します。したがって、値変数をインターフェイス変数に割り当てると、逆参照できない新しいコピーが作成され、ポインター レシーバー メソッドのレシーバーとして渡されます。
要約すると、ポインター レシーバー メソッドを使用してインターフェイスを実装する場合、ポインターのみが作成されます。実装型へのインターフェイスを満たすことができます。値の変数またはコピーは、必要なポインター レシーバーの型を提供できないため、このようなインターフェイスに割り当てることはできません。
以上が値レシーバーを使用して構造体を使用して、ポインター レシーバーを使用してインターフェイスを実行できないのはなぜですか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。