Советы по нарезке

задняя часть Go

использовать добавление

Давайте посмотрим на пример:

// 创建一个整型切片
// 其长度和容量都是 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]

Следующий рисунок может очень наглядно проиллюстрировать принцип работы приведенного выше кода:

image.png

С небольшим изменением результат будет другим:

	// 创建一个整型切片
	// 其长度和容量都是 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}}

Его структуру можно представить следующим рисунком:

image.png

Первое измерение можно рассматривать как длину 2, емкость 2 сохраняетсяломтикСрез типа, а второе измерение — целочисленный срез.

Другие правила такие же, как и для одномерных срезов, например:

// 为第一个切片追加值为 20 的元素 
slice[0] = append(slice[0], 20)

Вышеперечисленные операции можно представить следующей схемой:

image.png