использовать добавление
Давайте посмотрим на пример:
// 创建一个整型切片
// 其长度和容量都是 5 个元素
slice := []int{10, 20, 30, 40, 50}
// 创建一个新切片
// 其长度为 2 个元素,容量为 4 个元素
newSlice := slice[1:3]
// 使用原有的容量来分配一个新元素
// 将新元素赋值为 60,会改变底层数组中的元素
newSlice = append(newSlice, 60)
fmt.Println(slice, newSlice)
выход:
[10 20 30 60 50] [20 30 60]
Следующий рисунок может очень наглядно проиллюстрировать принцип работы приведенного выше кода:
С небольшим изменением результат будет другим:
// 创建一个整型切片
// 其长度和容量都是 5 个元素
slice := []int{10, 20, 30, 40, 50}
// 创建一个新切片
// 其长度与容量相同
newSlice := slice[1:3:3] // 注意这里
// 使用原有的容量来分配一个新元素
// 将新元素赋值为 60,会改变底层数组中的元素
newSlice = append(newSlice, 60)
// newSlice 的底层数组已经不是 slice 了,这个改变不会影响 slice
newSlice[0] = 0
fmt.Println(slice, newSlice, cap(newSlice))
Приведенный выше код выведет:
[10 20 30 40 50] [0 30 60] 4
Причина: когдаnewSlice
При добавлении новых элементов в , из-за недостаточной емкости,newSlice
будет иметьсовершенно новыйБазовый массив , емкость которого в два раза больше (Go делает это автоматически, когда количество элементов превышает 1000, коэффициент роста устанавливается равным 1,25)
использоватьrange
траверсslice
В использованииrange
траверсslice
когда,range
создаст копию каждого элемента, посмотрите на этот пример:
slice := []int{10, 20, 30, 40}
// 迭代每个元素,并显示值和地址
for index, value := range slice {
fmt.Printf("Value: %d Value-Addr: %X ElemAddr: %X\n", value, &value, &slice[index])
}
выход:
Value: 10 Value-Addr: C420014060 ElemAddr: C420018080
Value: 20 Value-Addr: C420014060 ElemAddr: C420018088
Value: 30 Value-Addr: C420014060 ElemAddr: C420018090
Value: 40 Value-Addr: C420014060 ElemAddr: C420018098
можно увидетьValue-Addr
а такжеElemAddr
Адреса разные, что подтверждает вышеизложенное. Адрес переменной на каждой итерации один и тот же, указывая на то, что процесс итерации повторно использует эту переменную, что также является способом предотвращения потери памяти.
многомерный срез
Создайте многомерный срез:
// 创建一个整型切片的切片
slice := [][]int{{10}, {100, 200}}
Его структуру можно представить следующим рисунком:
Первое измерение можно рассматривать как длину 2, емкость 2 сохраняетсяломтикСрез типа, а второе измерение — целочисленный срез.
Другие правила такие же, как и для одномерных срезов, например:
// 为第一个切片追加值为 20 的元素
slice[0] = append(slice[0], 20)
Вышеперечисленные операции можно представить следующей схемой: