func main() {
a := []string{"Hello1", "Hello2", "Hello3"}
fmt.Println(a)
// [Hello1 Hello2 Hello3]
a = append(a[:0], a[1:]...)
fmt.Println(a)
// [Hello2 Hello3]
}
Como esse truque de exclusão com a função de acréscimo funciona?
Parece que está pegando tudo antes do primeiro elemento (matriz vazia)
Em seguida, anexando tudo após o primeiro elemento (posição zero)
O que o ... (ponto ponto ponto) faz?
...
é explicado lá em detalhes?Respostas:
Onde
a
está a fatia ei
o índice do elemento que você deseja excluir:...
é uma sintaxe para argumentos variados no Go.Basicamente, ao definir uma função, coloca todos os argumentos que você passa em uma fatia desse tipo. Ao fazer isso, você pode passar quantos argumentos quiser (por exemplo,
fmt.Println
pode usar quantos argumentos quiser).Agora, ao chamar uma função,
...
faz o oposto: descompacta uma fatia e as passa como argumentos separados para uma função variável.Então, o que essa linha faz:
é essencialmente:
Agora, você pode estar se perguntando, por que não fazer
Bem, a definição de função de
append
éPortanto, o primeiro argumento deve ser uma fatia do tipo correto, o segundo argumento é o variável, então passamos uma fatia vazia e descompactamos o restante da fatia para preencher os argumentos.
fonte
a = append(a[:i], a[i+1:]...)
Existem duas opções:
R: Você se preocupa em manter a ordem da matriz:
B: Você não se preocupa em manter a ordem (isso provavelmente é mais rápido):
Veja o link para ver implicações sobre vazamentos de memória se sua matriz for de ponteiros.
https://github.com/golang/go/wiki/SliceTricks
fonte
Em vez de pensar nos índices nas anotações
[a:]
-,[:b]
- e -[a:b]
como índices de elementos, pense neles como os índices das lacunas ao redor e entre os elementos, começando com a lacuna indexada0
antes do elemento indexado como0
.Olhando apenas os números azuis, é muito mais fácil ver o que está acontecendo:
[0:3]
encerra tudo,[3:3]
está vazio e[1:2]
renderia{"B"}
. Então[a:]
é apenas a versão curta[a:len(arrayOrSlice)]
,[:b]
a versão curta[0:b]
e[:]
a versão curta de[0:len(arrayOrSlice)]
. O último é comumente usado para transformar uma matriz em uma fatia quando necessário.fonte
... é uma sintaxe para argumentos variados.
Eu acho que é implementado pelo complier usando slice (
[]Type)
, assim como a função anexa:quando você usa "elems" em "anexar", na verdade é uma fatia (do tipo []). Então "
a = append(a[:0], a[1:]...)
" significa "a = append(a[0:0], a[1:])
"a[0:0]
é uma fatia que não tem nadaa[1:]
é "Hello2 Hello3"É assim que funciona
fonte
a[0:0]
não énil
senão uma fatia com 0 comprimento.a[0:0]
será unicamente sernil
sea
énil
.Estou recebendo um erro de índice fora do intervalo com a solução de resposta aceita. Motivo: quando o intervalo inicia, não é o valor da iteração um por um, é a iteração pelo índice. Se você modificou uma fatia enquanto estiver dentro do alcance, isso causará algum problema.
Resposta antiga:
Esperado:
Real:
Maneira correta (solução):
Fonte: https://dinolai.com/notes/golang/golang-delete-slice-item-in-range-problem.html
fonte
No wiki do golang, ele mostra alguns truques para a fatia, incluindo a exclusão de um elemento da fatia.
Link: insira a descrição do link aqui
Por exemplo, a é a fatia que você deseja excluir o elemento número i.
OU
fonte