ホームページ  >  記事  >  バックエンド開発  >  `String()` メソッドで `% v` を使用すると、入れ子になった構造体で無限再帰が発生するのはなぜですか?

`String()` メソッドで `% v` を使用すると、入れ子になった構造体で無限再帰が発生するのはなぜですか?

Susan Sarandon
Susan Sarandonオリジナル
2024-11-05 14:56:02130ブラウズ

Why Does Using `% v` in a `String()` Method Lead to Infinite Recursion with Nested Structs?

String() 関数のネストされた構造体による無限再帰スタック オーバーフロー

次のネストされた構造体について考えます。

type ConfigOne struct {
    Daemon daemon
}

type daemon struct {
    Loglevel int
    Logfile string
}

ここで、ConfigOne 型で String() 文字列メソッドを定義すると仮定します。

func (c ConfigOne)String() string {
    return fmt.Sprintf("%+v\n", c)
}

この String() メソッドは、% v 形式指定子を使用して、ネストされた構造体要素の値を返そうとします。ただし、これにより、無限再帰スタック オーバーフロー エラーが発生します。

このエラーの理由は、型で実装されている場合、%v および % v 形式指定子が String() 関数の値を使用するためです。したがって、その型の String() 関数内の型に対して % v を使用すると、終了しない再帰呼び出しが作成されます。

このエラーを回避するには、String() 関数で % v を使用しないでください。代わりに、フィールド値に明示的にアクセスしてフォーマットすることにより、手動で文字列を構築する必要があります。

func (c ConfigOne)String() string {
    return fmt.Sprintf("Loglevel: %d, Logfile: %s\n", c.Daemon.Loglevel, c.Daemon.Logfile)
}

この変更された String() 関数は無限再帰を引き起こさず、ネストされた構造体要素の値を正しく出力します。 .

または、ネストされたデーモン構造体の String() メソッドをオーバーライドして再帰を防ぐこともできます。

func (d daemon)String() string {
    return fmt.Sprintf("Loglevel: %d, Logfile: %s\n", d.Loglevel, d.Logfile)
}

ネストされた構造体の String() メソッドをオーバーライドすると、再帰呼び出しチェーンを変更し、String() 関数が、その構造体に含まれるすべての構造体ではなく、ネストされた構造体自体の値のみを出力するようにします。

以上が`String()` メソッドで `% v` を使用すると、入れ子になった構造体で無限再帰が発生するのはなぜですか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

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