Estou tentando combinar a fatia [1, 2]
e a fatia [3, 4]
. Como posso fazer isso no Go?
Eu tentei:
append([]int{1,2}, []int{3,4})
mas conseguiu:
cannot use []int literal (type []int) as type int in append
No entanto, a documentação parece indicar que isso é possível, o que estou perdendo?
slice = append(slice, anotherSlice...)
go
append
slice
variadic-functions
Kevin Burke
fonte
fonte
append()
uma função variadica e...
permite passar vários argumentos para uma função variadic a partir de uma fatia.foo()
exemplo acima, ois
parâmetro contém uma cópia da fatia original, ou seja, possui uma cópia da referência leve para a mesma matriz subjacente, len e cap. Se afoo
função alterar um membro, a alteração será vista no original. Aqui está uma demonstração . Portanto, a única sobrecarga real será que ela cria uma nova fatia se você ainda não a possui, como:foo(1, 2, 3, 4, 5)
que criará uma nova fatia queis
será mantida....
uma fatia existente, ela simplesmente passa essa fatia. Quando você passa argumentos individuais, ele os reúne em uma nova fatia e a passa. Não tenho conhecimento de primeira mão da mecânica exatas, mas eu acho que isso:foo(1, 2, 3, 4, 5)
e isto:func foo(is ...int) {
apenas de-açúcar para isso:foo([]int{1, 2, 3, 4, 5})
e isto:func foo(is []int) {
.A resposta para sua pergunta é um exemplo
s3 := append(s2, s0...)
na Especificação da linguagem de programação Go . Por exemplo,fonte
a[low : high : max]
) que também especifica a capacidade máxima . Por exemplo, a fatiaa[0:2:4]
terá capacidade4
e não poderá ser realçada para incluir elementos além disso, mesmo que a matriz de suporte possua mil elementos depois disso.Nada contra as outras respostas, mas achei a breve explicação nos documentos mais facilmente compreensível do que os exemplos:
fonte
Eu acho importante salientar e saber que, se a fatia de destino (a que você anexa) tiver capacidade suficiente, o anexo ocorrerá "no local", realocando novamente o destino (realocando novamente para aumentar seu comprimento para ser capaz de acomodar os elementos anexáveis).
Isso significa que, se o destino tiver sido criado dividindo uma matriz ou fatia maior que possua elementos adicionais além do comprimento da fatia resultante, eles poderão ser substituídos.
Para demonstrar, veja este exemplo:
Saída (experimente no Go Playground ):
Criamos uma matriz "de apoio"
a
com comprimento10
. Em seguida, criamos ax
fatia de destino cortando essaa
matriz, ay
fatia é criada usando o literal composto[]int{3, 4}
. Agora, quando anexary
ax
, o resultado é o esperado[1 2 3 4]
, mas o que pode ser surpreendente é que a matriz de suportea
também mudou, porque a capacidade dex
seja10
o que é suficiente para anexary
a ele, assimx
é resliced que também usará o mesmoa
leque de apoio, eappend()
irá copiar elementos dey
para lá.Se você quiser evitar isso, use uma expressão de fatia completa que tenha o formato
que constrói uma fatia e também controla a capacidade da fatia resultante, configurando-a para
max - low
.Veja o exemplo modificado (a única diferença é que criamos
x
assimx = a[:2:2]
:Saída (experimente no Go Playground )
Como você pode ver, obtemos o mesmo
x
resultado, mas a matriz de backupa
não mudou, porque a capacidade dex
era "apenas"2
(graças à expressão de fatia completaa[:2:2]
). Para fazer o acréscimo, é alocada uma nova matriz de apoio que pode armazenar os elementos de ambosx
ey
, o qual é distintoa
.fonte
Gostaria de enfatizar a resposta do @icza e simplificá-la um pouco, pois é um conceito crucial. Presumo que o leitor esteja familiarizado com as fatias .
Esta é uma resposta válida para a pergunta. MAS, se você precisar usar as fatias 'a' e 'c' posteriormente no código em um contexto diferente, essa não é a maneira segura de concatenar as fatias.
Para explicar, vamos ler a expressão não em termos de fatias, mas em termos de matrizes subjacentes:
append () não cria necessariamente uma nova matriz! Isso pode levar a resultados inesperados. Veja o exemplo do Go Playground .
Sempre use a função make () se quiser garantir que uma nova matriz seja alocada para a fatia. Por exemplo, aqui estão algumas opções feias, mas eficientes o suficiente para a tarefa.
fonte
função append () e operador spread
Duas fatias podem ser concatenadas usando o
append
método na biblioteca golang padrão. O que é semelhante àvariadic
operação da função. Então, precisamos usar...
fonte
append([]int{1,2}, []int{3,4}...)
vai funcionar. Passando argumentos para...
parâmetros.Se
f
for variável com um parâmetro finalp
do tipo...T
, dentrof
do tipo dep
é equivalente ao tipo[]T
.Se
f
for invocado sem argumentos reais parap
, o valor passado parap
énil
.Caso contrário, o valor passado é uma nova fatia do tipo
[]T
com uma nova matriz subjacente cujos elementos sucessivos são os argumentos reais, aos quais todos devem ser atribuídosT
. O comprimento e a capacidade da fatia são, portanto, o número de argumentos vinculadosp
e podem diferir para cada site de chamada.Dada a função e chamadas
fonte