Estoy tratando de combinar el corte [1, 2]
y el corte [3, 4]
. ¿Cómo puedo hacer esto en Go?
Lo intenté:
append([]int{1,2}, []int{3,4})
pero tengo:
cannot use []int literal (type []int) as type int in append
Sin embargo, la documentación parece indicar que esto es posible, ¿qué me estoy perdiendo?
slice = append(slice, anotherSlice...)
go
append
slice
variadic-functions
Kevin Burke
fuente
fuente
append()
una función variable, y le...
permite pasar múltiples argumentos a una función variable desde un segmento.foo()
ejemplo anterior, elis
parámetro contiene una copia de la porción original, es decir, tiene una copia de la referencia ligera a la misma matriz subyacente, len y cap. Si lafoo
función altera a un miembro, el cambio se verá en el original. Aquí hay una demostración . Entonces, la única sobrecarga real será que crea un nuevo segmento si aún no lo tenía, como:foo(1, 2, 3, 4, 5)
lo que creará un nuevo segmento queis
se mantendrá....
en un segmento existente, simplemente pasa ese segmento. Cuando pasa argumentos individuales, los reúne en un nuevo segmento y lo pasa. No tengo conocimiento de primera mano de la mecánica exacta, pero supongo que esto:foo(1, 2, 3, 4, 5)
y esto:func foo(is ...int) {
Just de azúcares a esto:foo([]int{1, 2, 3, 4, 5})
y esto:func foo(is []int) {
.La respuesta a su pregunta es un ejemplo
s3 := append(s2, s0...)
en la especificación del lenguaje de programación Go . Por ejemplo,fuente
a[low : high : max]
) que también especifica la capacidad máxima . Por ejemplo, el segmentoa[0:2:4]
tendrá una capacidad de4
y no puede ser cortado para incluir elementos más allá de eso, ni siquiera si la matriz de respaldo tiene mil elementos después de eso.Nada en contra de las otras respuestas, pero encontré la breve explicación en los documentos más fácilmente comprensible que los ejemplos en ellos:
fuente
Creo que es importante señalar y saber que si la porción de destino (la porción a la que anexas) tiene capacidad suficiente, la adición se realizará "en el lugar", mediante la división del destino (la reducción para aumentar su longitud para ser capaz de acomodar los elementos anexables).
Esto significa que si el destino se creó cortando una matriz o segmento más grande que tiene elementos adicionales más allá de la longitud del segmento resultante, pueden sobrescribirse.
Para demostrarlo, vea este ejemplo:
Salida (pruébalo en Go Playground ):
Creamos una matriz de "respaldo"
a
con longitud10
. Luego creamos elx
segmento de destino dividiendo estaa
matriz, ely
segmento se crea utilizando el literal compuesto[]int{3, 4}
. Ahora, cuando añadimosy
ax
, el resultado es el esperado[1 2 3 4]
, pero lo que puede ser sorprendente es que el conjunto de respaldoa
también ha cambiado, ya que la capacidad dex
decir10
que es suficiente para anexary
a la misma, por lo quex
se resliced que también utilizar el mismoa
conjunto de respaldo, yappend()
copiará elementos dey
allí.Si desea evitar esto, puede usar una expresión de corte completo que tenga la forma
que construye un segmento y también controla la capacidad del segmento resultante configurándolo en
max - low
.Vea el ejemplo modificado (la única diferencia es que creamos
x
asíx = a[:2:2]
:Salida (pruébalo en Go Playground )
Como puede ver, obtenemos el mismo
x
resultado, pero la matriz de respaldoa
no cambió, porque la capacidad dex
era "solo"2
(gracias a la expresión de corte completoa[:2:2]
). Entonces, para hacer el apéndice, se asigna una nueva matriz de respaldo que puede almacenar los elementos de ambosx
yy
, que es diferente dea
.fuente
Me gustaría enfatizar la respuesta de @icza y simplificarla un poco, ya que es un concepto crucial. Supongo que el lector está familiarizado con las rebanadas .
Esta es una respuesta válida a la pregunta. PERO si necesita usar los segmentos 'a' y 'c' más adelante en el código en un contexto diferente, esta no es la forma segura de concatenar los segmentos.
Para explicar, leamos la expresión no en términos de sectores, sino en términos de matrices subyacentes:
¡append () no necesariamente crea una nueva matriz! Esto puede conducir a resultados inesperados. Vea el ejemplo de Go Playground .
Utilice siempre la función make () si desea asegurarse de que se asigne una nueva matriz para el segmento. Por ejemplo, aquí hay algunas opciones lo suficientemente feas pero eficientes para la tarea.
fuente
Función append () y operador de propagación
Se pueden concatenar dos
append
sectores utilizando el método de la biblioteca estándar de golang. Que es similar a lavariadic
operación de la función. Entonces necesitamos usar...
fuente
append([]int{1,2}, []int{3,4}...)
trabajará. Pasar argumentos a...
parámetros.Si
f
es variable con un parámetro finalp
de tipo...T
, entonces dentrof
del tipo dep
es equivalente a tipo[]T
.Si
f
se invoca sin argumentos reales parap
, el valor pasado ap
esnil
.De lo contrario, el valor pasado es una nueva porción de tipo
[]T
con una nueva matriz subyacente cuyos elementos sucesivos son los argumentos reales, a los que todos deben poder asignarseT
. La longitud y la capacidad del segmento es, por lo tanto, el número de argumentos vinculados ap
y pueden diferir para cada sitio de llamada.Dada la función y llamadas
fuente