最近、「[]*T」、「*[]T」、「*[]*T」などの非常に奇妙なコードを見つけました。一見するとすべて同じように見えますが、よく見ると、それらが違いであることがわかります。今日は、golong の "[]*T"、"*[]T"、および "*[]*T" を紹介し、それらの違いを理解し、一緒に見てみましょう
Go 言語初心者として「奇妙な」コードを見ると好奇心がそそられます。たとえば、最近見たいくつかのメソッドです。疑似コードは次のとおりです:
func FindA() ([]*T,error) { } func FindB() ([]T,error) { } func SaveA(data *[]T) error { } func SaveB(data *[]*T) error { }
Go を始めたばかりのほとんどの初心者もそのようなコードを見ることになると思います。混乱していますが、最も不可解なことは次のとおりです:
[]*T *[]T *[]*T
このスライスの宣言を記述する最後の 2 つの方法は見ません; []*T だけを見ても、まだ簡単に理解できます:
これすべての T のメモリ アドレスがスライスに保存されるため、T 自体を保存するよりも多くのスペースが節約されます。同時に、[]*T はメソッド内で T の値を変更できますが、[]T は変更できません。
func TestSaveSlice(t *testing.T) { a := []T{{Name: "1"}, {Name: "2"}} for _, t2 := range a { fmt.Println(t2) } _ = SaveB(a) for _, t2 := range a { fmt.Println(t2) } } func SaveB(data []T) error { t := data[0] t.Name = "1233" return nil } type T struct { Name string }
たとえば、上記の例では
{1} {2} {1} {2}
が出力されます。メソッドを
func SaveB(data []*T) error { t := data[0] t.Name = "1233" return nil }
に変更することによってのみ、T の値を変更できます。
&{1} &{2} &{1233} &{2}
[]*T と *[]T の違いに注目しましょう。ここには 2 つの追加関数が書かれています:
func TestAppendA(t *testing.T) { x:=[]int{1,2,3} appendA(x) fmt.Printf("main %v\n", x) } func appendA(x []int) { x[0]= 100 fmt.Printf("appendA %v\n", x) }
まず最初の関数を見てみましょう。出力は次のとおりです:
appendA [1000 2 3] main [1000 2 3]
関数の転送プロセス中に、関数内の変更が外部に影響を与える可能性があることを説明します。
別の例を見てみましょう:
func appendB(x []int) { x = append(x, 4) fmt.Printf("appendA %v\n", x) }
最終結果は次のとおりです:
appendA [1 2 3 4] main [1 2 3]
外部への影響はありません。
そして、もう一度調整すると、何か違うことがわかります:
func TestAppendC(t *testing.T) { x:=[]int{1,2,3} appendC(&x) fmt.Printf("main %v\n", x) } func appendC(x *[]int) { *x = append(*x, 4) fmt.Printf("appendA %v\n", x) }
最終結果:
appendA &[1 2 3 4] main [1 2 3 4]
スライスのポインタを渡すと、次のことがわかります。 append 関数を使用して追加します。データは外部から影響を受けます。
上記の 3 つの状況を分析する前に、まずスライスのデータ構造を理解しましょう。
ソース コードを直接見ると、スライスは実際には構造体であることがわかりますが、直接アクセスすることはできません。
ソース コード アドレス runtime/slice.go
3 つの重要な属性があります:
Attributes | Meaning |
---|---|
array | データを格納する基礎となる配列はポインターです。 |
スライス長 | |
スライス容量の上限>=len |
以上が大規模混乱シーンの[]*Tとは何ですか? *[]Tとは何ですか? *[]*Tそれは何ですか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。