Go の Stringer インターフェイスを使用する場合、ユーザーは String( ) メソッドは、非ポインター オブジェクトを fmt.Println に渡すときに呼び出されません。この動作を明らかにするために、次のコードを調べてみましょう:
package main import "fmt" type Car struct { year int make string } func (c *Car) String() string { return fmt.Sprintf("{make:%s, year:%d}", c.make, c.year) } func main() { myCar := Car{year: 1996, make: "Toyota"} fmt.Println(myCar) }
ここでは、Car 構造体を定義し、String() メソッドを値メソッドとして実装します。ただし、myCar を引数として fmt.Println に渡すと、オブジェクトはインターフェースに変換されます。{}これにより、fmt パッケージは String() メソッドをバイパスして、独自のデフォルトの書式設定を使用するようになります。
この動作を理解する鍵は、ポインター レシーバー (*) に String() メソッドを実装しているという事実にあります。車)。 Car 型の値を渡す場合、コンパイラーはそれをポインターに自動的に変換しません。したがって、fmt パッケージは String() メソッドと渡した値を一致させることができません。
代わりに、非ポインター オブジェクトを渡すときに String() メソッドを呼び出すには、値を手動で変換する必要があります。 & 演算子を使用したポインター:
fmt.Println(&myCar)
これにより、Car オブジェクトへのポインターを fmt.Println に渡します。これにより、値レシーバー String() メソッドが呼び出され、カスタム書式設定が適用されるようになります。
要約すると、Stringer インターフェイスを使用する場合は、メソッドが正しいレシーバー上で定義されている必要があることを覚えておくことが重要です。タイプ。ポインターの場合はポインター レシーバーが適切ですが、値型の場合は値レシーバーを使用できます。ポインターを手動で渡すことが望ましくない場合は、実際の Car 構造体にポインター メソッドとして String() メソッドを実装することを検討できます。
以上が非ポインター オブジェクトを使用するときに「fmt.Println」がストリンガー インターフェイス メソッドを呼び出さないのはなぜですか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。