Ausgaben: [<nil> <nil> <nil> <nil> <nil> 0xc010035160 0xc010035170 0xc010035180 0xc010035190 0xc0100351a0]
Was ich tun möchte, ist Speicher für 5 UselessStructs, die als Zeiger gespeichert werden. Wenn ich eine Schicht von Strukturwerten eq deklariere:
%Vor%erzeugt dann 5 leere Strukturen - das Anfügen ersetzt nicht die leeren Strukturen, sondern fügt dem Slice immer noch hinzu, also das Endergebnis mit diesem Code:
%Vor% ist: [{0 0} {0 0} {0 0} {0 0} {0 0} {0 0} {0 0} {0 0} {0 0} {0 0}]
Was ist der Weg, um Slices vorab zuzuweisen und zu füllen?
Für Ihr erstes Beispiel würde ich tun:
%Vor% Das Problem, mit dem Sie in beiden Beispielen konfrontiert werden, ist, dass Sie ein Segment anfügen, das bereits die richtige Länge hat. Wenn Sie mySlice := make([]*UselessStruct, 5)
setzen, fragen Sie nach einer Scheibe von Null-Zeigern der Länge 5. Wenn Sie einen Zeiger anhängen, hat er jetzt die Länge 6.
Stattdessen möchten Sie mySlice := make([]*UselessStruct, 0, 5)
verwenden. Dies erzeugt ein Stück der Länge 0, aber der Kapazität 5. Jedes Mal, wenn Sie es anhängen, wird eins zur Länge hinzugefügt, aber es wird nicht neu zugewiesen, bis Sie die Kapazität des Stücks überschreiten.
Beide meiner Beispiele funktionieren wie erwartet, aber ich empfehle die erste aus rein stilistischen Gründen.
Es gibt zwei Möglichkeiten, dies zu tun. Einer besteht darin, die Slots wie zuvor zuzuteilen.
Aber anstatt append
zu verwenden, indexieren Sie einfach in einen der vorhandenen Slots:
Die zweite ist, die 'überladene' Version von make
zu verwenden. Sie geben die Länge Null an, aber eine Kapazität von 5.
mySlice := make([]*T, 0, 5)
initialisiert das Slice mit einer Länge von Null, reserviert aber immer noch genügend Platz für 5 Einträge.
Sind Sie sicher, dass Sie Zeiger brauchen? Ihre Struktur hat einen Wert von 0, also:
%Vor%Und da Slices Referenztypen sind, haben Sie effektiv 5 Zeiger auf diese 5 UselessStructs.
Wenn Sie einen Verweis auf eine einzelne Struktur erhalten müssen, um herumzugehen, dann können Sie einfach so
%Vor%Und jetzt haben Sie einen Zeiger auf ein UseLessStruct, um zu verwenden, wie Sie für richtig halten. Es ist weit weniger Code als Sie haben und nutzt Go's Nullwert-Funktion.
Nur zur Vervollständigung: append arbeitet mit nil slice, also müssen Sie das slice nicht mit make erstellen, sondern einfach ein Element anhängen.
%Vor%Dies wird dasselbe wie vorheriges Beispiel ohne Vorabzuweisung tun, aber wenn Sie die Größe kennen, verwenden Sie eher etwas wie dieses:
%Vor%Dies kann eine Neuzuweisung vermeiden.