wake-up-neo.net

cap vs len der scheibe in golang

Was ist der Unterschied zwischen cap und len einer Scheibe in Golang?

Nach Definition:

Ein Slice hat sowohl eine Länge als auch eine Kapazität.

Die Länge eines Slice ist die Anzahl der Elemente, die es enthält.

Die Kapazität eines Slices ist die Anzahl der Elemente im darunter liegenden Array, die vom ersten Element des Slice aus gezählt werden.

x := make([]int, 0, 5) // len(b)=0, cap(b)=5

Bedeutet das len nur Nicht-Null-Werte?

15
Ali Adravi

Ein Slice ist eine Abstraktion, bei der ein Array unter den Deckblättern verwendet wird.

cap gibt die Kapazität des zugrunde liegenden Arrays an. len gibt an, wie viele Elemente sich im Array befinden.

Die Slice-Abstraktion in Go ist sehr schön, da die Größe des zugrundeliegenden Arrays für Sie geändert wird. In Go können Arrays nicht in der Größe geändert werden, sodass stattdessen fast immer Slices verwendet werden.

Beispiel:

s := make([]int, 0, 3)
for i := 0; i < 5; i++ {
    s = append(s, i)
    fmt.Printf("cap %v, len %v, %p\n", cap(s), len(s), s)
}

Wird so etwas ausgeben:

cap 3, len 1, 0x1040e130
cap 3, len 2, 0x1040e130
cap 3, len 3, 0x1040e130
cap 8, len 4, 0x10432220
cap 8, len 5, 0x10432220

Wie Sie sehen, sobald die Kapazität erreicht ist, gibt append ein neues Segment mit einer größeren Kapazität zurück. Bei der vierten Iteration werden Sie eine größere Kapazität und eine neue Zeigeradresse bemerken.

Spielbeispiel

Ich weiß, dass Sie nicht nach Arrays und Anhängen gefragt haben, aber sie sind ziemlich grundlegend, um das Slice und den Grund für die Builtins zu verstehen.

41
jmaloney

Aus dem Quellcode :

// The len built-in function returns the length of v, according to its type:
//  Array: the number of elements in v.
//  Pointer to array: the number of elements in *v (even if v is nil).
//  Slice, or map: the number of elements in v; if v is nil, len(v) is zero.
//  String: the number of bytes in v.
//  Channel: the number of elements queued (unread) in the channel buffer;
//  if v is nil, len(v) is zero.
func len(v Type) int

// The cap built-in function returns the capacity of v, according to its type:
//  Array: the number of elements in v (same as len(v)).
//  Pointer to array: the number of elements in *v (same as len(v)).
//  Slice: the maximum length the slice can reach when resliced;
//  if v is nil, cap(v) is zero.
//  Channel: the channel buffer capacity, in units of elements;
//  if v is nil, cap(v) is zero.
func cap(v Type) int
1
Tyler

Sie haben Ihre Frage beantwortet. Die Länge des zugrunde liegenden Arrays in einem Slice entspricht nicht unbedingt der Anzahl der Elemente, die das Array enthält.

0
daplho

@jmaloney

Ich habe dieses Ergebnis.

[email protected]:~/go/src/hello$ ./hello 
cap 3, len 1, 0xc000016460
cap 3, len 2, 0xc000016460
cap 3, len 3, 0xc000016460
cap 6, len 4, 0xc00001a240
cap 6, len 5, 0xc00001a240
0
Ali D.