ホームページ > バックエンド開発 > Golang > 値ベースのオブジェクトを渡すときに fmt.Println がストリンガー インターフェイスの String メソッドを呼び出さないのはなぜですか?

値ベースのオブジェクトを渡すときに fmt.Println がストリンガー インターフェイスの String メソッドを呼び出さないのはなぜですか?

Susan Sarandon
リリース: 2024-12-06 19:35:15
オリジナル
478 人が閲覧しました

Why Doesn't fmt.Println Invoke My Stringer Interface's String Method When Passing a Value-Based Object?

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 つのオプションがあります:

  1. Car に文字列を実装する(値ベース): これには、値レシーバー上で動作する Car 用の別の String メソッドを作成する必要があります。これにより、不必要なオブジェクトのコピーが発生します。
  2. 常にポインターを fmt.Println: fmt.Println(&myCar) を使用すると、渡された値の *Car タイプが正しいことを確認でき、String メソッドが次のように呼び出されます。

以上が値ベースのオブジェクトを渡すときに fmt.Println がストリンガー インターフェイスの String メソッドを呼び出さないのはなぜですか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

ソース:php.cn
このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。
著者別の最新記事
人気のチュートリアル
詳細>
最新のダウンロード
詳細>
ウェブエフェクト
公式サイト
サイト素材
フロントエンドテンプレート