ホームページ >バックエンド開発 >Golang >空の構造体へのポインターの配列を比較すると一貫性のない結果が生じるのはなぜですか?

空の構造体へのポインターの配列を比較すると一貫性のない結果が生じるのはなぜですか?

Susan Sarandon
Susan Sarandonオリジナル
2024-12-28 20:59:16742ブラウズ

Why Do Comparisons of Arrays of Pointers to Empty Structs Produce Inconsistent Results?

空の構造体との配列比較で異なる結果が生じる理由

空の構造体へのポインタの配列が与えられた場合に、配列の等価比較が行われるのはなぜですかtrue と評価される場合もあれば、true と評価される場合もありますfalse?

動作の探索

package main

import "fmt"

type myStruct struct{}

func main() {
    s, ss := myStruct{}, myStruct{}
    arr1 := [6]*myStruct{&s}
    arr2 := [6]*myStruct{&ss}
    fmt.Println(&s == &ss, arr1 == arr2)  // Produces mixed results (e.g., false, true or true, false)

    l, ll := myStruct{A: 1}, myStruct{A: 1}
    arr3 := [6]*myStruct{&l}
    arr4 := [6]*myStruct{&ll}
    fmt.Println(&l == &ll, arr3 == arr4)  // Always evaluates to false
}

説明

Go 言語仕様には次のように記載されています。

  • サイズがゼロの個別の変数へのポインタは、等しい。
  • 構造体または配列にゼロ以外のサイズのフィールド (または要素) が含まれていない場合、そのサイズはゼロになります。
  • 2 つの異なるサイズ 0 の変数は、メモリ内で同じアドレスを持つ可能性があります。

動的行動と逃走分析

この動作は、Go コンパイラーによって実行されるエスケープ分析を考慮することで説明できます。

  • 最初の例では、変数 s と ss はエスケープしません (つまり、 、他の関数への参照によって渡されることはありません)。これは、コンパイラがそれらをメモリ内に割り当てる際の柔軟性が高く、同じアドレスを割り当てることができることを意味します。
  • 2 番目の例では、fmt.Printf 呼び出し (s と ss の両方をエスケープする) を追加すると、コンパイラが移動します。変数をヒープに追加すると、メモリ アドレスが異なるため、&l == に対して false が返されます。 &ll.

影響

  • ポインタの同一性に基づいて空の構造体の配列の同一性を比較することは信頼できません。
  • エスケープ分析は、このような比較の動作に大きな影響を与える可能性があります。

以上が空の構造体へのポインターの配列を比較すると一貫性のない結果が生じるのはなぜですか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

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