Preciso fazer uma cópia de uma fatia no Go e, lendo os documentos, há uma função de cópia à minha disposição.
A função interna de cópia copia elementos de uma fatia de origem em uma fatia de destino. (Como um caso especial, ele também copiará bytes de uma string para uma fatia de bytes.) A origem e o destino podem se sobrepor. Copiar retorna o número de elementos copiados, que será o mínimo de len (src) e len (dst).
Mas quando eu faço:
arr := []int{1, 2, 3}
tmp := []int{}
copy(tmp, arr)
fmt.Println(tmp)
fmt.Println(arr)
Meu tmp
está vazio como estava antes (eu até tentei usar arr, tmp
):
[]
[1 2 3]
Você pode verificá-lo no playground . Então, por que não consigo copiar uma fatia?
dst
deve ter pelo menos o tamanho de muitos elementos que você deseja copiar (para uma cópia completasrc
significalen(dst) >= len(src)
).b := append([]int{}, a...)
Respostas:
O builtin
copy(dst, src)
copiamin(len(dst), len(src))
elementos.Portanto, se o seu
dst
estiver vazio (len(dst) == 0
), nada será copiado.Experimente
tmp := make([]int, len(arr))
( Go Playground ):Saída (conforme o esperado):
Infelizmente, isso não está documentado no
builtin
pacote, mas está documentado na especificação de idioma Go: anexando e copiando fatias :Editar:
Finalmente, a documentação de
copy()
foi atualizada e agora contém o fato de que o comprimento mínimo de origem e destino será copiado:fonte
copy
não contém lógica para aumentar a fatia de destino se a fatia de destino for muito pequena, mas há outra função interna que faz isso:append
embora neste exemplo seja melhor alocar a fatia de tamanho certo em primeiro lugar,append
pode ser usado quando você já tem uma fatia e deseja aumentá-la adicionando elementos ao final.Outra maneira simples de fazer isso é usar o
append
que alocará a fatia no processo.Saída (conforme o esperado):
Portanto, um atalho para copiar array
arr
seriaappend([]int(nil), arr...)
https://play.golang.org/p/sr_4ofs5GW
fonte
Se suas fatias fossem do mesmo tamanho, funcionaria :
Daria:
Em " Go Slices: uso e componentes internos ":
O exemplo usual é:
fonte
A cópia () é executada pelo menor tamanho de dst e src, portanto, você deve inicializar o dst com o comprimento desejado.
Resultado:
Você pode inicializar e copiar todos os elementos em uma linha usando append () em uma fatia nula.
Exemplo:
Resultado:
Comparando com alocação + copy (), para mais de 1.000 elementos, use append. Na verdade, abaixo de 1.000, a diferença pode ser negligenciada; faça uma regra geral, a menos que você tenha muitas fatias.
fonte
tmp
precisa de espaço suficiente paraarr
. Por exemplo,Resultado:
fonte
Aqui está uma maneira de copiar uma fatia. Estou um pouco atrasado, mas há uma resposta mais simples e rápida do que a de Dave. Estas são as instruções geradas a partir de um código como o @ Dave. Estas são as instruções geradas pela minha. Como você pode ver, há muito menos instruções. O que é faz é apenas faz
append(slice)
, que copia a fatia. Este código:Emite isso:
fonte