Go のポインター: Printf の書式設定を理解する
Go では、ポインターは参照によって変数を渡す際に重要な役割を果たします。ただし、提供されているコード例に見られるように、それらを使用すると予期しない結果が生じる場合があります。詳細を調べて矛盾を解決しましょう。
問題:
コードは 2 つの変数を出力しようとしています。1 つはテスト構造体 (&test1) へのポインターで、もう 1 つはテスト構造体 (&test1) へのポインターです。もう 1 つはマップ (&test2) からの値です。これらの値を出力すると異なる出力が生成されるため、この問題が発生します。
説明:
矛盾を理解する鍵は fmt.Printf 関数にあります。この関数は、形式文字列と、interface{} 型の可変数の引数を受け取ります。
最初のケースでは、&test1 は *Test 型であり、fmt.Printf に渡されると、これは、interface{} 値でラップされます。ポインターのデフォルトの形式は %p で、値の 16 進アドレスが出力されます。したがって、出力は「0xc00009e190」になります。
対照的に、&test2 のタイプは *interface{} です。 fmt.Printf に渡されると、別のインターフェース値でラップされます。{} Interface{} 値のデフォルトの形式は %v であり、基になる型によって異なります。{}この場合、基になる型はインターフェイスへのポインタです。{}、ポインタの %v 形式は %p です。したがって、出力も 16 進アドレスになりますが、*interface{} 値のアドレスの場合は「0xc00029c0a0」となります。
解決策:
取得するにはtest2 の構造体の値、型アサーションを使用できます。これは基本的に、test2 に格納されている値が Test 構造体であると想定し、それを適切にキャストします。
test2 := Models["test"].(Test)
この変更により、test2 は Test 型になり、fmt.Printf に渡されると、 &test1 と同じ出力。
ベスト プラクティス:
です。一般に、型アサーションや中間変数宣言の必要性を避けるために、 *Test 値をマップに直接格納することが推奨されます。これにより、マップに格納されているインターフェイス値がすでに Test へのポインターになっていることが保証され、そのまま使用して渡すことができます。
以上が構造体へのポインタとマップ値へのポインタを出力するとき、Go の `fmt.Printf` 出力が異なるのはなぜですか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。