Колпачок против len ломтика в голанге

В чем разница между кепкой и линией среза в golang?

Согласно определению:

Срез имеет как длину, так и емкость.

Длина среза - это количество содержащихся в нем элементов.

Емкость среза - это количество элементов в базовом массиве, считая от первого элемента в срезе.

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

Значит ли len только значения, отличные от нуля?

Ответ 1

Срез - это абстракция, которая использует массив под обложками.

cap указывает емкость базового массива. len сообщает, сколько элементов находится в массиве.

Абстракция среза в Go очень приятная, так как она изменит размер базового массива для вас, а также массивы Go не могут быть изменены, поэтому срезы почти всегда используются.

Пример:

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)
}

Выведет что-то вроде этого:

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

Как только вы увидите, как только производительность будет достигнута, append вернет новый срез с большей емкостью. На 4-й итерации вы увидите большую емкость и новый адрес указателя.

Пример воспроизведения

Я понимаю, что вы не спрашивали о массивах и добавляете, но они довольно основательны в понимании среза и причине встроенных функций.

Ответ 2

Из исходного кода:

// 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

Ответ 3

Вы ответили на свой вопрос: длина базового массива в срезе не обязательно совпадает с количеством элементов, содержащихся в массиве.

Ответ 4

@jmaloney

У меня есть этот результат.

[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