ホームページ > バックエンド開発 > Golang > `String()` メソッドにポインタ レシーバを使用すると、Go 文字列フォーマットでのデッド ループが防止されるのはなぜですか?

`String()` メソッドにポインタ レシーバを使用すると、Go 文字列フォーマットでのデッド ループが防止されるのはなぜですか?

Linda Hamilton
リリース: 2024-11-23 04:06:20
オリジナル
443 人が閲覧しました

Why Does Using a Pointer Receiver for `String()` Method Prevent a Dead Loop in Go String Formatting?

Go 文字列フォーマットにおける "t" と "*t" の違いを理解する

Go プログラムでは、変数名にプレフィックスを付けることができますポインターの種類を示すアスタリスク (*) が付いています。この区別は、fmt パッケージを使用した文字列フォーマットのコンテキストにおいて重要です。

質問:

次のコードを考えてください:

package main

import "fmt"

type TT struct {
    a int
    b float32
    c string
}

func (t *TT) String() string {
    return fmt.Sprintf("%+v", *t)
}

func main() {
    tt := &TT{3, 4, "5"}
    fmt.Printf(tt.String())
}
ログイン後にコピー

理由String にポインター レシーバー (func (t *TT) String() string) がある場合、コードは機能しますが、レシーバーが存在する場合、デッド ループが発生します。は非ポインタ型 (func (t TT) String() string) ですか?

答え:

fmt パッケージは String() の存在をチェックします。受け取るオペランドのメソッド。 String の受信側がポインター型の場合、基本型のメソッド セットには String() が含まれていないため、fmt パッケージはそれを呼び出しません。

一方、受信側が非ポインターの場合は、 type の String() は、基本型のメソッド セットに含まれます。これは、fmt パッケージが String() を呼び出すことを意味します。この場合、これは呼び出されるのと同じメソッドであり、無限ループにつながります。

予防:

回避するにはこの無限ループでは、type キーワードを使用して新しい型を作成し、書式設定されている値に型変換を適用することを検討してください。

func (t TT) String() string {
    type TT2 TT
    return fmt.Sprintf("%+v", TT2(t))
}
ログイン後にコピー

Thisこのアプローチでは、type キーワードによって作成された新しい型内で String() メソッドを分離することで、間接的な再帰を防ぎます。

以上が`String()` メソッドにポインタ レシーバを使用すると、Go 文字列フォーマットでのデッド ループが防止されるのはなぜですか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

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