Я думаю, что важно указать и знать, что, если срез назначения (срез, к которому вы добавляете) имеет достаточную емкость, добавление произойдет «на месте», путем изменения назначения (с целью увеличения его длины, чтобы быть в состоянии разместить дополняемые элементы).
Это означает, что если место назначения было создано путем нарезки большего массива или среза, у которого есть дополнительные элементы, превышающие длину полученного среза, они могут быть перезаписаны.
Чтобы продемонстрировать, посмотрите этот пример:
a := [10]int{1, 2}
fmt.Printf("a: %v\n", a)
x, y := a[:2], []int{3, 4}
fmt.Printf("x: %v, y: %v\n", x, y)
fmt.Printf("cap(x): %v\n", cap(x))
x = append(x, y...)
fmt.Printf("x: %v\n", x)
fmt.Printf("a: %v\n", a)
Вывод (попробуйте на Go Playground ):
a: [1 2 0 0 0 0 0 0 0 0]
x: [1 2], y: [3 4]
cap(x): 10
x: [1 2 3 4]
a: [1 2 3 4 0 0 0 0 0 0]
Мы создали «резервный» массив aс длиной 10. Затем мы создаем xсрез назначения, разрезая этот aмассив, yсрез создается с использованием составного литерала []int{3, 4}. Теперь , когда мы добавляем yк x, результат является ожидаемым [1 2 3 4], но то , что может быть удивительного в том , что массив поддержка aтакже изменился, потому что способность xIS , 10которая достаточна для добавления yк нему, так xкак resliced , который также будет использовать тот же aмассив подкладочный и append()скопирую элементы yтуда.
Если вы хотите избежать этого, вы можете использовать полное выражение слайса, которое имеет вид
a[low : high : max]
который создает срез, а также управляет емкостью результирующего среза, установив его в max - low.
Смотрите модифицированный пример (единственное отличие в том, что мы создаем xтак x = a[:2:2]:
a := [10]int{1, 2}
fmt.Printf("a: %v\n", a)
x, y := a[:2:2], []int{3, 4}
fmt.Printf("x: %v, y: %v\n", x, y)
fmt.Printf("cap(x): %v\n", cap(x))
x = append(x, y...)
fmt.Printf("x: %v\n", x)
fmt.Printf("a: %v\n", a)
Выход (попробуйте на Go Playground )
a: [1 2 0 0 0 0 0 0 0 0]
x: [1 2], y: [3 4]
cap(x): 2
x: [1 2 3 4]
a: [1 2 0 0 0 0 0 0 0 0]
Как вы можете видеть, мы получаем тот же xрезультат, но резервный массив aне изменился, потому что емкость xбыла «единственной» 2(благодаря полному выражению слайса a[:2:2]). Таким образом, чтобы выполнить добавление, выделяется новый резервный массив, который может хранить элементы обоих xи yотличных от a.
append()функция с переменным числом, и...позволяет передавать несколько аргументов функции с переменным срезом.