ホームページ  >  記事  >  バックエンド開発  >  Go でネストされた構造体の印刷がゴルーチンのスタック オーバーフローを引き起こすのはなぜですか?

Go でネストされた構造体の印刷がゴルーチンのスタック オーバーフローを引き起こすのはなぜですか?

Barbara Streisand
Barbara Streisandオリジナル
2024-11-04 19:37:02744ブラウズ

Why Does Nested Struct Printing Lead to Goroutine Stack Overflow in Go?

ランタイム エラー: ネストされた構造体による Goroutine スタック オーバーフロー

Go でネストされた構造体を扱うときは、潜在的なスタックに注意することが重要ですオーバーフローします。これは、構造体の String() メソッドに依存する形式を使用してネストされた構造体を出力しようとすると発生する可能性があります。

根本原因:

次の場合に無限再帰が発生します。構造体の String() メソッドは、同じ構造体をフィールドの 1 つとして出力しようとします。 %v および % v 形式では、String() の値が存在する場合はそれを使用します。これにより、無限ループが作成され、スタック オーバーフローが発生します。

例:

次のネストされた構造体と String() メソッドを考えてみましょう:

<code class="go">type ConfigOne struct {
    // Daemon section from config file.
    Daemon daemon
}

type daemon struct {
    Loglevel int
    Logfile string
}

func (c ConfigOne) String() string {
    return fmt.Sprintf("%+v\n", c) // Uses %+v for nested structs
}</code>

この String() メソッドを使用して ConfigOne のインスタンスを印刷しようとすると、スタック オーバーフロー エラーが発生します:

<code class="go">c := &modules.ConfigOne{}
c.Daemon.Loglevel = 1
c.Daemon.Logfile = "/tmp/test.log"
modules.Logger.Infoln(c.String())</code>

解決策:

無限を避けるには再帰とスタック オーバーフローが発生した場合は、String() メソッドで文字列を手動で構築し、ネストされた構造体に必要な形式を指定する必要があります。例:

<code class="go">func (c ConfigOne) String() string {
    return fmt.Sprintf("Loglevel: %d, Logfile: %s\n", c.Daemon.Loglevel, c.Daemon.Logfile)
}</code>

この場合、String() メソッドは %v または % v を使用せずにネストされたフィールドを明示的にフォーマットし、無限再帰の問題を解決します。

以上がGo でネストされた構造体の印刷がゴルーチンのスタック オーバーフローを引き起こすのはなぜですか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

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