Я думаю, что важно указать и знать, что, если срез назначения (срез, к которому вы добавляете) имеет достаточную емкость, добавление произойдет «на месте», путем изменения назначения (с целью увеличения его длины, чтобы быть в состоянии разместить дополняемые элементы).
Это означает, что если место назначения было создано путем нарезки большего массива или среза, у которого есть дополнительные элементы, превышающие длину полученного среза, они могут быть перезаписаны.
Чтобы продемонстрировать, посмотрите этот пример:
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
также изменился, потому что способность x
IS , 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()
функция с переменным числом, и...
позволяет передавать несколько аргументов функции с переменным срезом.