func main() {
a := []string{"Hello1", "Hello2", "Hello3"}
fmt.Println(a)
// [Hello1 Hello2 Hello3]
a = append(a[:0], a[1:]...)
fmt.Println(a)
// [Hello2 Hello3]
}
¿Cómo funciona este truco de eliminación con la función append?
Parece que está agarrando todo antes del primer elemento (matriz vacía)
Luego, agregue todo después del primer elemento (posición cero)
¿Qué hace el ... (dot dot dot)?
...
se explica allí en detalle?Respuestas:
Dónde
a
está el segmento yi
es el índice del elemento que desea eliminar:...
es la sintaxis para argumentos variados en Go.Básicamente, al definir una función, coloca todos los argumentos que pasa en una porción de ese tipo. Al hacerlo, puede pasar tantos argumentos como desee (por ejemplo,
fmt.Println
puede tomar tantos argumentos como desee).Ahora, cuando se llama a una función,
...
hace lo contrario: desempaqueta un segmento y los pasa como argumentos separados a una función variable.Entonces, qué hace esta línea:
Es esencial:
Ahora, te estarás preguntando, ¿por qué no solo hacer
Bueno, la definición de la función
append
esEntonces, el primer argumento tiene que ser un segmento del tipo correcto, el segundo argumento es el variadic, por lo que pasamos un segmento vacío y luego desempaquetamos el resto del segmento para completar los argumentos.
fuente
a = append(a[:i], a[i+1:]...)
Hay dos opciones:
A: le importa retener el orden de la matriz:
B: No te importa retener el orden (probablemente esto sea más rápido):
Vea el enlace para ver las implicaciones de las pérdidas de memoria si su matriz es de punteros.
https://github.com/golang/go/wiki/SliceTricks
fuente
En lugar de pensar en los índices en las anotaciones
[a:]
-,[:b]
- y -[a:b]
como índices de elementos, piense en ellos como los índices de los huecos alrededor y entre los elementos, comenzando con el espacio indexado0
antes del elemento indexado como0
.Mirando solo los números azules, es mucho más fácil ver lo que está sucediendo:
[0:3]
encierra todo,[3:3]
está vacío y[1:2]
cedería{"B"}
. Entonces[a:]
es solo la versión corta de[a:len(arrayOrSlice)]
,[:b]
la versión corta de[0:b]
y[:]
la versión corta de[0:len(arrayOrSlice)]
. Este último se usa comúnmente para convertir una matriz en un segmento cuando es necesario.fuente
... es sintaxis para argumentos variados.
Creo que es implementado por el cumplidor usando slice (
[]Type)
, al igual que la función append:cuando usas "elems" en "append", en realidad es un segmento (tipo []). Entonces "
a = append(a[:0], a[1:]...)
" significa "a = append(a[0:0], a[1:])
"a[0:0]
es una rebanada que no tiene nadaa[1:]
es "Hola2 Hola3"Así es como funciona
fuente
a[0:0]
no esnil
sino una rebanada con 0 de longitud.a[0:0]
será solamente sernil
sia
esnil
.Estoy obteniendo un error de índice fuera de rango con la solución de respuesta aceptada. Motivo: cuando se inicia el rango, no es un valor iterativo uno por uno, es iterar por índice. Si modificó un segmento mientras está dentro del rango, provocará algún problema.
Vieja respuesta:
Esperado :
Real:
Forma correcta (solución):
Fuente: https://dinolai.com/notes/golang/golang-delete-slice-item-in-range-problem.html
fuente
En el wiki de golang, muestra algunos trucos para el corte, incluida la eliminación de un elemento del corte.
Enlace: ingrese la descripción del enlace aquí
Por ejemplo, a es el segmento en el que desea eliminar el elemento número i.
O
fuente