Доступ к элементам slice
Значение из slice читается по индексу: укажите номер его позиции в квадратных скобках.
Позиции отсчитываются с 0, поэтому [0] — первый элемент, [1] — второй, и так далее до конца slice.
Пример
Вывод индексов 0 и 2 показывает первое и третье значения в prices:
Вывод: программа на Go и захваченный вывод
package main
import ("fmt")
func main() {
prices := []int{10, 20, 30}
fmt.Println(prices[0])
fmt.Println(prices[2])
}
Изменение элементов slice
Присваивание по индексу перезаписывает значение, которое там хранится.
Пример
Третье значение в prices меняется с 30 на 50:
Вывод: программа на Go и захваченный вывод
package main
import ("fmt")
func main() {
prices := []int{10, 20, 30}
prices[2] = 50
fmt.Println(prices[0])
fmt.Println(prices[2])
}
Добавление элементов в slice
Функция append() добавляет новые значения после последнего элемента. Присвойте её результат обратно в slice, как показывает синтаксис:
Пример
Два новых значения, 20 и 21, добавляются в конец myslice1. Его длина увеличивается с 6 до 8, а ёмкость растёт, чтобы освободить место:
Вывод: программа на Go и захваченный вывод
package main
import ("fmt")
func main() {
myslice1 := []int{1, 2, 3, 4, 5, 6}
fmt.Printf("myslice1 = %v\n", myslice1)
fmt.Printf("длина = %d\n", len(myslice1))
fmt.Printf("ёмкость = %d\n", cap(myslice1))
myslice1 = append(myslice1, 20, 21)
fmt.Printf("myslice1 = %v\n", myslice1)
fmt.Printf("длина = %d\n", len(myslice1))
fmt.Printf("ёмкость = %d\n", cap(myslice1))
}
Синтаксис
slice_name = append(slice_name, element1, element2, ...)
Добавление одного slice к другому
append() может также добавить целый slice в конец другого, как показывает синтаксис.
Примечание: Три точки после slice2 обязательны. Они указывают Go передавать элементы slice по одному.
Пример
Значения myslice2 идут после значений myslice1, а объединённый результат попадает в myslice3:
Вывод: программа на Go и захваченный вывод
package main
import ("fmt")
func main() {
myslice1 := []int{1, 2, 3}
myslice2 := []int{4, 5, 6}
myslice3 := append(myslice1, myslice2...)
fmt.Printf("myslice3=%v\n", myslice3)
fmt.Printf("длина=%d\n", len(myslice3))
fmt.Printf("ёмкость=%d\n", cap(myslice3))
}
Синтаксис
slice3 = append(slice1, slice2...)
Изменение длины slice
Длина массива фиксирована, а длина slice может меняться.
Пример
myslice1 сначала охватывает четыре элемента arr1, затем его повторно нарезают до двух. Добавление четырёх значений увеличивает его до шести, что превышает его ёмкость 5, поэтому ёмкость тоже растёт:
Вывод: программа на Go и захваченный вывод
package main
import ("fmt")
func main() {
arr1 := [6]int{9, 10, 11, 12, 13, 14}
myslice1 := arr1[1:5]
fmt.Printf("myslice1 = %v\n", myslice1)
fmt.Printf("длина = %d\n", len(myslice1))
fmt.Printf("ёмкость = %d\n", cap(myslice1))
myslice1 = arr1[1:3]
fmt.Printf("myslice1 = %v\n", myslice1)
fmt.Printf("длина = %d\n", len(myslice1))
fmt.Printf("ёмкость = %d\n", cap(myslice1))
myslice1 = append(myslice1, 20, 21, 22, 23)
fmt.Printf("myslice1 = %v\n", myslice1)
fmt.Printf("длина = %d\n", len(myslice1))
fmt.Printf("ёмкость = %d\n", cap(myslice1))
}
Эффективность использования памяти
Slice держит в памяти весь свой базовый массив, даже если вы используете лишь небольшую его часть.
Поэтому, когда массив большой, а вам нужно лишь несколько его элементов, лучше скопировать их с помощью функции copy().
Скопируйте их в новый slice, и этот slice получит собственный базовый массив, содержащий только то, что вам нужно. Тогда ваша программа будет использовать меньше памяти.
Пример
numbers содержит 15 значений, но нужны только первые 5. Они копируются в numbersCopy, созданный с помощью make(), длина и ёмкость которого равны всего 5:
Вывод: программа на Go и захваченный вывод
package main
import ("fmt")
func main() {
numbers := []int{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15}
// Исходный slice
fmt.Printf("numbers = %v\n", numbers)
fmt.Printf("длина = %d\n", len(numbers))
fmt.Printf("ёмкость = %d\n", cap(numbers))
// Создаём копию только с нужными числами
neededNumbers := numbers[:len(numbers)-10]
numbersCopy := make([]int, len(neededNumbers))
copy(numbersCopy, neededNumbers)
fmt.Printf("numbersCopy = %v\n", numbersCopy)
fmt.Printf("длина = %d\n", len(numbersCopy))
fmt.Printf("ёмкость = %d\n", cap(numbersCopy))
}
Синтаксис
copy() принимает два slice — приёмник dest и источник src — и копирует данные из источника в приёмник. Её возвращаемое значение сообщает, сколько элементов было скопировано.
copy(dest, src)