Die folgende Kolumne stellt Golang Make allen in der Kolumne Golang-Tutorial vor. Ich hoffe, dass es für Freunde hilfreich ist, die es brauchen!
Golang verfügt hauptsächlich über integrierte neue und make-Funktionen zum Zuweisen von Speicher. Heute werden wir untersuchen, wie make gespielt werden kann.
map kann nur Speicher für Slice, Map und Channel zuweisen und einen initialisierten Wert zurückgeben. Schauen wir uns zunächst die folgenden drei verschiedenen Verwendungsmöglichkeiten von make an:
1 make([]int, 2)
3 , 4 )
1. Die erste Verwendung besteht darin, Parameter mit fehlender Länge und nur den Typ zu übergeben. Diese Verwendung kann nur in Szenarien verwendet werden, in denen der Typ „map“ oder „chan“ ist ein Fehler. Die auf diese Weise zurückgegebene Leerzeichenlänge ist standardmäßig 0.
2. Bei der zweiten Verwendung wird die Länge angegeben. Make([]int, 2) gibt beispielsweise ein Segment mit einer Länge von 2 zurück.
3 Bei der dritten Verwendung gibt der zweite Parameter die Länge an Der dritte Parameter wird verwendet, um die Länge des reservierten Speicherplatzes anzugeben, z. B. a := make([]int, 2, 4). Hierbei ist zu beachten, dass die Gesamtlänge des zurückgegebenen Slice a 4 beträgt. Reserviert bedeutet nicht, dass die zusätzliche Länge von 4 tatsächlich die Anzahl der ersten beiden Slices umfasst. Wenn Sie beispielsweise := make([]int, 4, 2) verwenden, wird ein Syntaxfehler gemeldet.
Wenn wir einem Slice Speicher zuweisen, sollten wir daher unser Bestes geben, um die mögliche maximale Länge des Slice abzuschätzen, und durch Übergabe des dritten Parameters Speicherplatz für das Slice reservieren, um eine sekundäre Speicherzuweisung zu vermeiden Der dadurch verursachte Overhead verbessert die Leistung des Programms erheblich.
Tatsächlich ist es für uns schwierig, die mögliche maximale Länge des Slice abzuschätzen. Wenn wir in diesem Fall append aufrufen, um Elemente an den Slice anzuhängen, weist Golang nicht jedes Mal zweimal Speicher zu, um die sekundäre Zuweisung zu reduzieren Es wird jeweils nur eine Speichereinheit hinzugefügt, und es folgt ein solcher Erweiterungsmechanismus:
Wenn ungenutzter Speicherplatz reserviert ist, wird der ungenutzte Speicherplatz direkt in Scheiben geschnitten und angehängt Der reservierte Speicherplatz ist aufgebraucht, der Erweiterungsraum beträgt das Doppelte der aktuellen Slice-Länge. Beispielsweise beträgt die aktuelle Slice-Länge 4. Nach einer Anhängeoperation beträgt die von cap(a) zurückgegebene Länge 8. Schauen Sie sich das an der folgende Democode:
package main import ( "fmt") func main() { a := make([]int, 0) n := 20 for i := 0; i < n; i++ { a = append(a, 1) fmt.Printf("len=%d cap=%d\n", len(a), cap(a)) } } Output: len=1 cap=1 // 第一次扩容len=2 cap=2 // 第二次扩容len=3 cap=4 // 第三次扩容len=4 cap=4len=5 cap=8 // 第四次扩容len=6 cap=8len=7 cap=8len=8 cap=8len=9 cap=16 // 第五次扩容len=10 cap=16len=11 cap=16len=12 cap=16len=13 cap=16len=14 cap=16len=15 cap=16len=16 cap=16len=17 cap=32 // 第六次扩容len=18 cap=32len=19 cap=32len=20 cap=32
Die obigen Testergebnisse zeigen, dass sich die Speicherplatzlänge nach jeder Erweiterung verdoppelt.
Ich bin neugierig und möchte es versuchen. Wenn es sich weiter ausdehnt, wird es theoretisch exponentiell wachsen. Wird dies jedoch weiterhin der Fall sein, und die anschließende Ausgabe sieht so aus?
0 0 1 1 2 2 4 4 8 8 16 16 32 32 64 64 128 128 256 256 512 512 1024 1024 1312 1312 // 288 1696 1696 // 384 2208 2208 // 512 3072 3072 // 864 4096 4096 // 1024 5120 5120 // 1024 7168 7168 // 2048 9216 9216 // 2048
Die obige Ausgabe Die Situation, in der es in der Mitte keine Erweiterung gibt, wird ignoriert. Es ist zu erkennen, dass die ersten 11 Erweiterungen die Länge jedes Mal verdoppelten, die 12. Erweiterung jedoch offensichtlich nicht wie erwartet bis 2048 expandierte.
Das obige ist der detaillierte Inhalt vonÜber Golang machen. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!