この記事では、PHP エディターの Xiaoxin が、X による Y の実装の失敗に関する問題について説明します。この問題では、ポインター レシーバーのアプローチを使用しました。この方法を通じて、X が Y を達成できない理由をよりよく理解し、この問題を解決する方法を見つけることができます。次のコンテンツでは、この問題について詳しく説明し、いくつかの解決策を提供します。
「XX は Y を実装していません (...メソッドにはポインタ レシーバがあります)」という質問についてはいくつかの Q&A がありますが、私にとっては、彼らは別のことについて話しているようで、私の特定の状況には当てはまりません。
そこで、質問を非常に具体的にする代わりに、広く抽象的な質問にします。このエラーが発生する原因となる可能性のある状況がいくつかあるようですが、誰かがそれを要約できますか?この問題を回避するにはどうすればよいですか?また、この問題が発生した場合はどのような可能性がありますか?ありがとう。 回避策このコンパイル時エラーは、
concrete 型をインターフェイス型に割り当てたり渡したり (または変換) しようとしたときに発生しますが、型自体はこのインターフェイスを実装すると、型への ポインター のみが実装されます。
短い概要: 変数への代入 インターフェイス型は、割り当てられた値が、割り当て先のインターフェイスを実装する場合に有効です。その メソッド セット がインターフェイスのスーパーセットである場合、それを実装します。ポインター型のメソッド セットには、ポインター レシーバーと非ポインター レシーバーを持つメソッドが含まれます。非ポインター型のメソッド セット のみ には、非ポインター レシーバーを持つメソッドが含まれます。 例を見てみましょう:
リーリー stringer インターフェイス タイプには、メソッド string()
が 1 つだけあります。インターフェイス値 stringer
に格納されている値には、このメソッドが必要です。また、mytype
を作成し、pointer
レシーバーを備えたメソッド mytype.string() を作成しました。これは、string()
メソッドが *mytype
型の メソッド セット
に含まれていますが、mytype には含まれていないことを意味します。
の値を stringer
型の変数に代入しようとすると、次のエラーが表示されます:
リーリー
しかし、
型の値を stringer
に代入しようとすると、すべて正常に動作します。
リーリー
期待どおりの結果が得られます (
go playground
リーリー したがって、このコンパイル時エラーが発生するには、次のものが必要です:
割り当てられた (または渡された、または変換された)
非ポインター値へのポインターを使用する必要があり、そのメソッド セットにはポインター レシーバーを持つメソッドが含まれます
struct に埋め込まれた型です。この例のように:
リーリー
mytype2
のメソッド セットには
に埋め込まれた string()
メソッドが含まれておらず、* のみが含まれているため、再コンパイル時にエラーが発生しました。 mytype2
メソッドが設定されているため、次のメソッドが有効です ( のプレイグラウンドに移動します):
リーリー
*mytype を埋め込み、
mytype2
を使用するだけでも機能させることができます ( のプレイグラウンドに移動します)。
リーリー
また、何を埋め込んだとしても (
mytype または *mytype
*mytype2 给定一个结构体类型 换句话说:如果我们嵌入一个非指针类型,非指针嵌入器的方法集只能获取具有非指针接收器的方法(来自嵌入类型)。 如果我们嵌入一个指针类型,非指针嵌入器的方法集将获取具有指针和非指针接收器的方法(来自嵌入类型)。 如果我们使用指向嵌入器的指针值,则无论嵌入类型是否是指针,指向嵌入器的指针的方法集始终都会获取具有指针和非指针接收器的方法(从嵌入类型)。 注意: 有一个非常相似的情况,即当您有一个包含 运行时恐慌(在 go playground 上尝试一下): 尝试转换而不是类型断言,我们得到了我们正在讨论的编译时错误: を使用すると、常に機能します (# で) # #ゴガン
):
リーリー
仕様内の関連セクション ( 構造タイプ
セクションから):
s
和一个名为 t
的类型,提升的方法包含在该结构体的方法集中,如下所示:
s
包含匿名字段 t
,则 s
和 *s
的方法集均包含接收者为 t
的提升方法。 *s
的方法集还包括接收者 *t
的提升方法。s
包含匿名字段 *t
,则 s
和 *s
的方法集都包含接收者为 t
或 *t
的提升方法。mytype
值的接口值时,并且您尝试 类型断言 另一个接口值,stringer
。在这种情况下,由于上述原因,断言将不成立,但我们会得到一个略有不同的运行时错误:m := mytype{value: "something"}
var i interface{} = m
fmt.println(i.(stringer))
panic: interface conversion: main.mytype is not main.stringer:
missing method string
m := MyType{value: "something"}
fmt.Println(Stringer(m))
以上がX は Y を実装していません (...メソッドにはポインタ レシーバがあります)の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。