Println とのストリンガー インターフェイスの混乱: 値ベースのオブジェクトとポインター ベースのオブジェクトの理解
質問:
オブジェクトが Stringer インターフェイスを実装するシナリオでは、なぜオブジェクトが値ベースの場合、fmt.Println を使用すると、オブジェクトの String メソッドが呼び出されませんか?
コード例:
次の Go コードを考えてみましょう:
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) }
myCar がポインターの場合、期待どおり String メソッドが呼び出されます。ただし、myCar が値の場合は、デフォルトの Go フォーマットが代わりに使用されます。
回答:
この動作の理由は、Go インターフェイスの動作方法にあります。インターフェイスを実装する型 (この場合は Stringer) を指定すると、Go はその型がインターフェイスの正確な型であることを期待します。 Car 型の値を fmt.Println に渡すと、その値は暗黙的にインターフェイス{}に変換され、インターフェイス{} 型システムには Car 型は存在しません。{}代わりに、型 *Car (Car へのポインター) です。
fmt.Println 関数は、型スイッチを使用して、その型に基づいて値を出力する方法を決定します。 Stringer インターフェイスの場合、値が String メソッドを実装しているかどうかをチェックします。 Car (値ベース) は String を実装していないため、デフォルトの書式設定が使用されます。ただし、myCar.String() を明示的に呼び出すと、コンパイラはそれを (&myCar).String() に自動的に変換します。これは正しい *Car 型を持ち、必要な書式設定メソッドを呼び出します。
オブジェクトはそのタイプに関係なく希望どおりにフォーマットされます。次の 2 つのオプションがあります:
以上が値ベースのオブジェクトを渡すときに fmt.Println がストリンガー インターフェイスの String メソッドを呼び出さないのはなぜですか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。