В посте о срезах мы написали функцию Append для добавления элементов в срез:
func Append(slice, data []byte) []byte {
l := len(slice)
if l + len(data) > cap(slice) { // реаллоцируем
// Аллоцирем в двойном размере требуемого,
// для будущего роста.
newSlice := make([]byte, (l+len(data))*2)
// copy функция предопределена
// и работает для любого типа среза.
copy(newSlice, slice)
slice = newSlice
}
slice = slice[0:l+len(data)]
copy(slice[l:], data)
return slice
}
Сигнатура append
отличается от нашей пользовательской функции Append
выше. Схематически:
func append(slice []T, elements ...T) []T
где T является заполнителем для любого данного типа. Вы не можете на самом деле написать функцию в Go, где тип T
определяется вызывающим абонентом. Вот почему append
встроен: он уждается в поддержке со стороны компилятора.
Что append
делает - это добавляет элементы в конец среза и возвращает результат. Результат нужно вернуть потому что, как и в случае с нашим рукописным Append
, основной массив может измениться. Вот простой пример:
x := []int{1,2,3}
x = append(x, 4, 5, 6)
fmt.Println(x)
печатает [1 2 3 4 5 6]
. Таким образом, append
работает немного похоже на Printf
, собирая произвольное число аргументов.
Но что, если мы хотим сделать то, что делает наш Append
, и добавить срез в срез? Легко: используйте ...
при вызове места, как мы это делали при вызове Output
выше. Следующий пример выдает результат, идентичный приведенному выше.
x := []int{1,2,3}
y := []int{4,5,6}
x = append(x, y...)
fmt.Println(x)
Без этого ...
он не скомпилируется, потому что типы были бы неправильные; y
не относится к типу int
.
Читайте также:
Комментариев нет:
Отправить комментарий