Muszę zrobić kopię wycinka w Go i po przeczytaniu dokumentów mam do dyspozycji funkcję kopiowania .
Wbudowana funkcja copy kopiuje elementy z wycinka źródłowego do wycinka docelowego. (W specjalnym przypadku kopiuje również bajty z łańcucha do fragmentu bajtów). Źródło i miejsce docelowe mogą się nakładać. Copy zwraca liczbę skopiowanych elementów, która będzie minimum len (src) i len (dst).
Ale kiedy robię:
arr := []int{1, 2, 3}
tmp := []int{}
copy(tmp, arr)
fmt.Println(tmp)
fmt.Println(arr)
Mój tmp
jest pusty, jak wcześniej (próbowałem nawet użyć arr, tmp
):
[]
[1 2 3]
Możesz to sprawdzić na placu zabaw . Dlaczego więc nie mogę skopiować kawałka?
dst
powinno mieć co najmniej tyle elementów, które chcesz skopiować (pełna kopiasrc
oznacza tolen(dst) >= len(src)
).b := append([]int{}, a...)
Odpowiedzi:
Wbudowane
copy(dst, src)
kopiujemin(len(dst), len(src))
elementy.Więc jeśli twój
dst
jest pusty (len(dst) == 0
), nic nie zostanie skopiowane.Wypróbuj
tmp := make([]int, len(arr))
( Go Playground ):Wyjście (zgodnie z oczekiwaniami):
Niestety nie jest to udokumentowane w
builtin
pakiecie, ale jest udokumentowane w specyfikacji języka Go: Dołączanie do plasterków i kopiowanie :Edytować:
Ostatecznie
copy()
zaktualizowano dokumentację i obecnie zawiera ona fakt, że skopiowana zostanie minimalna długość źródła i celu:źródło
copy
nie zawiera logiki do powiększania wycinka docelowego, jeśli wycinek docelowy jest zbyt mały, ale istnieje inna wbudowana funkcja, która to robi:append
Podczas gdy w tym przykładzie lepiej jest po prostu przydzielić wycinek o odpowiednim rozmiarze w pierwszej kolejności,append
może być używany, gdy masz już plasterek i chcesz go wyhodować, dodając elementy na końcu.Innym prostym sposobem na to jest użycie,
append
które przydzieli wycinek w procesie.Wyjście (zgodnie z oczekiwaniami):
Więc skrótem do kopiowania tablicy
arr
byłobyappend([]int(nil), arr...)
https://play.golang.org/p/sr_4ofs5GW
źródło
Gdyby twoje plasterki były tego samego rozmiaru, zadziałałoby :
Dałby:
Z „ Go Slices: use and internals ”:
Typowy przykład to:
źródło
Copy () działa dla najmniejszej długości dst i src, więc musisz zainicjować dst do żądanej długości.
Wynik:
Możesz zainicjować i skopiować wszystkie elementy w jednej linii za pomocą funkcji append () do zerowego plasterka.
Przykład:
Wynik:
W porównaniu z alokacją + copy (), dla ponad 1000 elementów użyj dołączania. W rzeczywistości poniżej 1000 różnica może być zaniedbana, zrób to według zasady, chyba że masz wiele plasterków.
źródło
tmp
potrzebuje wystarczająco dużo miejscaarr
. Na przykład,Wynik:
źródło
Oto sposób na skopiowanie plasterka. Jestem trochę spóźniony, ale jest prostsza i szybsza odpowiedź niż @ Dave's. To są instrukcje wygenerowane z kodu takiego jak @ Dave's. To są instrukcje wygenerowane przeze mnie. Jak widać, instrukcji jest znacznie mniej. Po prostu robi
append(slice)
, kopiuje kawałek. Ten kod:Wyprowadza to:
źródło