Go の埋め込み構造体の奇妙なメソッド呼び出し: String() について
Go では、埋め込み構造体はその埋め込み型のメソッドを継承します。ただし、複数の埋め込み型が同じ名前のメソッドを定義すると、あいまいさが生じます。特に String() メソッドに焦点を当てて、この動作を調べてみましょう。
提供されたコード例では、
type Engineer struct { Person TaxPayer Specialization string } type Person struct { Name string Age int } func (p Person) String() string { return fmt.Sprintf("name: %s, age: %d", p.Name, p.Age) } type TaxPayer struct { TaxBracket int } func (t TaxPayer) String() string { return fmt.Sprintf("%d", t.TaxBracket) }
エンジニア構造体が fmt.Println(engineer) を使用して出力されると、出力は、埋め込み型に String() メソッドが存在するかどうかによって異なります。
With Person.String():
なしPerson.String():
両方の String() なしメソッド:
これらのシナリオは、Go のプロモートされたメソッドの深さルールと曖昧さの解決に焦点を当てています。ただし、深さが 0 の String() メソッドが複数存在する場合、なぜコンパイル時にあいまいさが検出されないのかという疑問が生じます。
Ambiguous Selector Check:
通常、engineer.Foo() などのあいまいなセレクターを使用してメソッドを呼び出そうとすると、コンパイル時エラーが発生します。ただし、これは String() という名前のメソッドでは発生しません。
理由:
String() メソッドを明示的に呼び出さずに値を出力する場合、fmt.Println関数は、値が fmt.Stringer を実装しているかどうかをチェックします。次に、実装された String() メソッドを呼び出します。すべての Go 型はデフォルトで暗黙的に Stringer を実装するため (https://golang.org/doc/go1.19#fmt)、どの型に対しても常に昇格された String() メソッドが存在します。
結論:
埋め込み構造体のメソッド呼び出しのあいまいさは、深さのルールと、値を出力するための String() メソッド。これらのルールとメソッド プロモーションの微妙な違いを理解することで、開発者は予期しない動作を回避し、Go プログラムのコードの明瞭さを維持できます。
以上がコンパイル時に埋め込み構造体の String() メソッド呼び出しのあいまいさを検出しないのはなぜですか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。