ホームページ  >  記事  >  バックエンド開発  >  競合する `String()` メソッドを含む型を埋め込むと、Go の `fmt.Println` が予期しない出力を生成するのはなぜですか?

競合する `String()` メソッドを含む型を埋め込むと、Go の `fmt.Println` が予期しない出力を生成するのはなぜですか?

Patricia Arquette
Patricia Arquetteオリジナル
2024-11-24 09:08:10291ブラウズ

Why Does Go's `fmt.Println` Produce Unexpected Output When Embedding Types with Conflicting `String()` Methods?

埋め込み型での 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)
}

Whenこのコードが実行されると、次の出力が生成されます。

{name: John Doe, age: 35 3 Construction}

埋め込みメソッド内に複数の String() メソッドが定義されているため、この結果は混乱するように見えるかもしれません。タイプは個人と納税者です。ただし、この曖昧さは次のルールによって解決されます。

  • 複数の埋め込み型で String() メソッドが定義されている場合、それは「不正なセレクター」とみなされ、(エンジニアを呼び出すことによって) 直接アクセスできないことを意味します。 .String() など).
  • その結果、どの String() メソッドも埋め込み型 (Engineer) に昇格されないため、デフォルトの書式設定 (フィールド値の出力) が使用されます。
  • ただし、fmt パッケージが Engineer 値のデフォルトの文字列表現を生成しようとすると、その値が fmt.Stringer インターフェイス ( String() メソッド).
  • Person 型は fmt.Stringer を実装しているため、その String() メソッドが呼び出され、フィールド (名前) の文字列表現が生成されます。

Person.String() メソッドまたは TaxPayer.String() メソッドを削除するとあいまいさが解決され、残りの String() メソッドをデフォルトの書式設定に使用できるようになります。

この動作から得られる重要な点は、埋め込み型は、単一の明確なメソッドが定義されている場合にのみ String() メソッドを促進するということです。複数のメソッドが存在する場合、埋め込み型には昇格された String() メソッドがなく、デフォルトの書式設定が使用されます。

以上が競合する `String()` メソッドを含む型を埋め込むと、Go の `fmt.Println` が予期しない出力を生成するのはなぜですか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。