Heim > Artikel > Backend-Entwicklung > Was ist []*T in der groß angelegten Verwirrungsszene? *[]Was ist T? *[]*TWas ist das?
Kürzlich habe ich einen sehr seltsamen Code gesehen, darunter „[]*T“, „*[]T“ und „*[]*T“. Auf den ersten Blick sehen sie alle gleich aus, aber wenn wir genau hinschauen, erkennen wir Wir finden, dass sie unterschiedlich sind. Heute stellen wir Golongs „[]*T“, „*[]T“ und „*[]*T“ vor, um die Unterschiede zwischen ihnen zu verstehen. Werfen wir einen Blick darauf. Schauen wir uns als Neuling in der Go-Sprache um Sie werden neugierig sein, wenn Sie einen „seltsamen“ Code sehen; der Pseudocode ist zum Beispiel wie folgt:
func FindA() ([]*T,error) { } func FindB() ([]T,error) { } func SaveA(data *[]T) error { } func SaveB(data *[]*T) error { }
Ich glaube, dass die meisten Anfänger, die gerade mit Go begonnen haben, verwirrt sein werden, wenn sie solchen sehen Code, und das Verwirrendste ist, worüber die Leute verwirrt sind:
[]*T *[]T *[]*T
Für eine solche Deklaration von Slices schauen wir uns nicht die letzten beiden Schreibweisen an; es ist leicht zu verstehen, wenn man sich []*T allein ansieht : Die Speicheradressen aller T werden in diesem Slice gespeichert, was besser ist als das Speichern von T selbst und mehr Platz spart. Gleichzeitig kann []*T den Wert von T innerhalb der Methode ändern, aber []T kann nicht.
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 }
Zum Beispiel gibt das obige Beispiel
{1} {2} {1} {2}Nur durch Ändern der Methode in
func SaveB(data []*T) error { t := data[0] t.Name = "1233" return nil }kann der Wert von T geändert werden:
&{1} &{2} &{1233} &{2}BeispielKonzentrieren wir uns auf den Unterschied zwischen []*T und *[] T, hier habe ich zwei Anhängefunktionen geschrieben:
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]Das bedeutet, dass sich Änderungen innerhalb der Funktion während des Funktionsübertragungsprozesses auf die Außenseite auswirken können.
Schauen wir uns ein anderes Beispiel an:
func appendB(x []int) { x = append(x, 4) fmt.Printf("appendA %v\n", x) }
appendA [1 2 3 4] main [1 2 3]hat nach außen keine Auswirkung. Und wenn wir es erneut anpassen, werden wir etwas anderes finden:
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) }Das Endergebnis:
appendA &[1 2 3 4] main [1 2 3 4]Sie können feststellen, dass sich die Verwendung der Append-Funktion zum Anhängen von Daten auf die Außenseite auswirkt, wenn Sie den Zeiger des Slice übergeben. Slice-PrinzipBevor wir die oben genannten drei Situationen analysieren, wollen wir zunächst die Datenstruktur von Slice verstehen. Wenn Sie sich den Quellcode direkt ansehen, werden Sie feststellen, dass es sich bei Slice tatsächlich um eine Struktur handelt, auf die jedoch nicht direkt zugegriffen werden kann. Quellcode-Adresse runtime/slice.goEs gibt drei wichtige Attribute:
len | |
cap | |
Das obige ist der detaillierte Inhalt vonWas ist []*T in der groß angelegten Verwirrungsszene? *[]Was ist T? *[]*TWas ist das?. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!