Мне нужно сделать копию фрагмента в Go и, читая документы, в моем распоряжении есть функция копирования .
Встроенная функция копирования копирует элементы из исходного слоя в целевой. (В особом случае он также копирует байты из строки в часть байтов.) Источник и место назначения могут перекрываться. Копирование возвращает количество скопированных элементов, которое будет минимум len (src) и len (dst).
Но когда я сделаю:
arr := []int{1, 2, 3}
tmp := []int{}
copy(tmp, arr)
fmt.Println(tmp)
fmt.Println(arr)
Мой tmp
по-прежнему пуст (даже пробовал использовать arr, tmp
):
[]
[1 2 3]
Вы можете проверить это на игровой площадке . Так почему я не могу скопировать срез?
dst
должно быть не меньше, чем количество элементов, которые вы хотите скопировать (для полной копииsrc
это означаетlen(dst) >= len(src)
).b := append([]int{}, a...)
Ответы:
Встроенная функция
copy(dst, src)
копируетmin(len(dst), len(src))
элементы.Поэтому, если ваш
dst
пустой (len(dst) == 0
), ничего не будет скопировано.Попробуйте
tmp := make([]int, len(arr))
( Go Playground ):Результат (как и ожидалось):
К сожалению, это не задокументировано в
builtin
пакете, но задокументировано в спецификации языка Go: добавление и копирование фрагментов :Редактировать:
Наконец, документация
copy()
была обновлена, и теперь она содержит тот факт, что минимальная длина источника и назначения будет скопирована:источник
copy
не содержит логики для увеличения целевого среза, если целевой срез слишком мал, но есть другая встроенная функция, которая делает:append
хотя в этом примере лучше просто выделить срез правильного размера в первую очередь,append
можно использовать, когда у вас уже есть срез и вы хотите его увеличить, добавляя элементы в конец.Другой простой способ сделать это - использовать
append
which, чтобы выделить фрагмент в процессе.Результат (как и ожидалось):
Таким образом, сокращение для копирования массива
arr
будетappend([]int(nil), arr...)
https://play.golang.org/p/sr_4ofs5GW
источник
Если бы ваши срезы были одинакового размера, это сработало бы :
Даст:
Из « Go Slices: использование и внутреннее устройство »:
Обычный пример:
источник
Copy () работает с наименьшей длиной dst и src, поэтому вы должны инициализировать dst до желаемой длины.
Вывод:
Вы можете инициализировать и скопировать все элементы в одну строку с помощью append () в нулевой срез.
Пример:
Вывод:
По сравнению с allocation + copy () для более чем 1000 элементов используйте append. На самом деле ниже 1000 разницей можно пренебречь, воспользуйтесь эмпирическим правилом, если у вас не много ломтиков.
источник
tmp
нужно достаточно места дляarr
. Например,Вывод:
источник
Вот способ скопировать срез. Я немного опоздал, но есть более простой и быстрый ответ, чем у @Dave. Это инструкции, сгенерированные из кода, подобного @ Dave's. Это инструкции, созданные мной. Как видите, инструкций гораздо меньше. Что делает, так это просто
append(slice)
копирует срез. Этот код:Выводит это:
источник