埋め込み 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) } func main() { engineer := Engineer{ Person: Person{ Name: "John Doe", Age: 35, }, TaxPayer: TaxPayer{3}, Specialization: "Construction", } fmt.Println(engineer) }
このコードの出力は、「名前: John Doe、年齢: 35 3 Construction」です。最初は不可解なこの動作は、埋め込み型が String() メソッドとどのように相互作用するかを調べることで説明できます。
埋め込み型のプロモーション
Go では、埋め込み型により次のことが可能になります。他の型のフィールドとメソッドを含めること。型が別の型を埋め込む場合、埋め込まれた型のフィールドとメソッドは埋め込み型に昇格され、埋め込み型で定義されているかのように動作します。この例では、Engineer タイプに Person タイプと TaxPayer タイプの両方が埋め込まれています。
メソッドの選択
埋め込まれたタイプで String() メソッドが呼び出されたときのデフォルトの動作その名前の最も浅い (ネストが最も浅い) メソッドを選択することです。ただし、同じ深さに昇格された String() メソッドが複数ある場合、セレクター式は不正となり、コンパイル時エラーが発生します。
提供されたコードでは、Person 型と TaxPayer 型の両方に String() があります。方法。したがって、Engineer.String() は不正なセレクターです。その結果、エンジニア値を出力するときに String() メソッドが直接呼び出されることはありません。
fmt Package String Generation
明示的な String() がない場合struct 型に対してメソッドが定義されている場合、fmt パッケージはフィールド値の出力を含むデフォルトの文字列表現に戻ります。 Engineer 構造体では、これにより、「名前: John Doe、年齢: 35 3 Construction」という出力が得られます。
メソッドを削除した効果
興味深いことに、いずれかの Person が削除されます。 .String() または TaxPayer.String() は曖昧さを解決し、残りの String() メソッドを文字列に使用できるようにします。 世代。これは、埋め込み型を使用するときにメソッドの命名規則を慎重に検討することの重要性を強調しています。
結論
埋め込み型の String() メソッドの動作は、明確さの必要性を強調しています。メソッドを定義するときの先見の明。メソッドの選択とプロモーションの仕組みを理解することで、開発者はあいまいなセレクターを回避し、その型の一貫した文字列表現を確保できます。
以上がGo の `String()` メソッドは、埋め込み型と複数のプロモートされたメソッドでどのように動作しますか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。