Сегодня поговорим о Slice в Golang.

Go

Предисловие:
Из-за рабочих потребностей я недавно связался с Голангом.
Я также надеюсь, что мой стек технологий можно будет трансформировать с iOS на iOS/Golang.


Итак, сегодня поговорим о массивах в Голанге (Array) и нарезать (Slice).

1. Массив (массив)

Мы все должны быть знакомы с массивами.
Массивы в языке Go (Array) после инициализации длина фиксируется.

Как и в других языках, вот несколько простых демонстраций массивов в Go.

var arr [10]int // 声明,len与cap为10,值默认补0。
arr := []int {1,2,3,4} // 快速声明,len与cap为4,值为[1,2,3,4]。
arr := [5]int {1,2,3,4} // 快速声明,len与cap为5,值为[1,2,3,4,0],末尾默认补0。

// 数组的遍历
for i := 0; i < len(arr); i++ {
	fmt.Println(arr[i])
}

2. Нарезать

Следующий главный герой сегодняшнего дня: Слайс.

Во-первых, срез является ссылочным типом. (со словаремmap,рядchannelто же самое, оба являются ссылочными типами)
Немного похоже на нашу iOSMutableArray.
На данный момент его можно понимать как «динамический массив» переменной длины.

Уведомление:
Поэтому, когда мы берем срез массива, если мы не хотим, чтобы модификация среза влияла на исходный массив, нам нужноSliceпровестиCopyработать.

основное использование

numbers := []int{1,2,3,4,5,6,7,8,9,10}

// 半闭半开结构
slice1 := numbers[:] // 直接对numbers的引用
slice1 = numbers[1:10] // 从numbers[1]到numbers[9]
slice1 = numbers[:5] // 从开始到numbers[4]
slice1 = numbers[7:] // 从numbers[7]开始到末尾

slice1 = append(slice1, 1,2,3,4,5) // 追加长度
fmt.Println(slice1) // 打印:[8 9 10 1 2 3 4 5]

slice2 := make([]int, len(slice1), cap(slice1)*2) // 手动声明一个slice2,最大长度cap为slice1的两倍。
copy(slice2,slice1) //将slice1的数据copy到slice2
slice2 = append(slice2,1,2,3) // 在对slice2进行追加

fmt.Println(slice1)  // 打印:[8 9 10 1 2 3 4 5]
fmt.Println(slice2)  // 打印:[8 9 10 1 2 3 4 5 1 2 3]

fmt.Printf("len = %d, cap = %d", len(slice1), cap(slice1)) // 打印当前长度len,与最大容量cap。

Стратегия расширения

когдаSliceдлина(len) вот-вот превысит максимальную вместимость (cap), язык Go будетSliceРасширять.

Конкретные стратегии:

  • когдаSliceдлина(len) меньше чем1024, язык Go будетSliceпровести"2x" расширение.
  • когдаSliceдлина(len) больше или равно1024, язык Go будетSliceпровестиРасширение "1,25 раза".
len Стратегия расширения
<1024 2x расширение
>=1024 расширение в 1,25 раза

Примечание. Спасибо Ролле за добавление: когда одно расширение не может удовлетворить условиям, оно будет расширяться до размера n+1 целевой длины.

Заинтересованные студенты могут использовать следующий код, чтобы попробовать стратегию расширения.

slice2 := make([]int,10,10)
fmt.Printf("len = %d, cap = %d\n", len(slice2), cap(slice2)) // 打印当前长度len,与最大容量cap。 // 获取len与cap的长度。
slice2 = append(slice2, 1,2,3,4,5) // 追加数据
fmt.Printf("len = %d, cap = %d\n", len(slice2), cap(slice2)) // 打印当前长度len,与最大容量cap。 // 获取len与cap的长度。

Некоторые точки внимания (яма)

  1. Не забывайте помнить, что срез является ссылочным типом. Если вы не хотите изменять исходные данные при изменении значения среза, вы должны сначала сделать копию.

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