recorrer golang array go slice

array - golang size



¿Por qué no puedo duplicar un segmento con `copy()` en Golang? (5)

La especificación del lenguaje de programación Go

Agregar y copiar sectores

La función copy copia elementos de corte de un src de origen a un dst de destino y devuelve el número de elementos copiados. Ambos argumentos deben tener un tipo de elemento idéntico T y deben poder asignarse a un segmento de tipo [] T. El número de elementos copiados es el mínimo de len (src) y len (dst). Como un caso especial, copy también acepta un argumento de destino asignable al tipo [] byte con un argumento fuente de un tipo de cadena. Este formulario copia los bytes de la cadena en el segmento de bytes.

copy(dst, src []T) int copy(dst []byte, src string) int

tmp necesita suficiente espacio para arr . Por ejemplo,

package main import "fmt" func main() { arr := []int{1, 2, 3} tmp := make([]int, len(arr)) copy(tmp, arr) fmt.Println(tmp) fmt.Println(arr) }

Salida:

[1 2 3] [1 2 3]

Necesito hacer una copia de un segmento en Go y leer los documentos hay una función de copy a mi disposición.

La función integrada copiar copia elementos de un segmento de origen en un segmento de destino. (Como caso especial, también copiará bytes de una cadena a una porción de bytes). El origen y el destino pueden superponerse. Copiar devuelve el número de elementos copiados, que será el mínimo de len (src) y len (dst).

Pero cuando lo hago:

arr := []int{1, 2, 3} tmp := []int{} copy(tmp, arr) fmt.Println(tmp) fmt.Println(arr)

Mi tmp está vacío como estaba antes (incluso intenté usar arr, tmp ):

[] [1 2 3]

Puedes consultarlo en ir al playground . Entonces, ¿por qué no puedo copiar una rebanada?


La copy incorporada copy copia elementos min(len(dst), len(src)) .

Entonces, si su dst está vacía ( len(dst) == 0 ), no se copiará nada.

Pruebe tmp := make([]int, len(arr)) ( Go Playground ):

arr := []int{1, 2, 3} tmp := make([]int, len(arr)) copy(tmp, arr) fmt.Println(tmp) fmt.Println(arr)

Salida (como se esperaba):

[1 2 3] [1 2 3]

Desafortunadamente, esto no está documentado en el paquete builtin , pero sí está documentado en la Especificación de idioma de Go: Agregar y copiar segmentos :

El número de elementos copiados es el mínimo de len(src) y len(dst) .

Editar:

Finalmente, la documentación de copy() se ha actualizado y ahora contiene el hecho de que se copiará la longitud mínima de origen y destino:

Copiar devuelve el número de elementos copiados, que será el mínimo de len (src) y len (dst).


La copia () se ejecuta con la menor longitud de dst y src, por lo que debe inicializar la dst a la longitud deseada.

A := []int{1, 2, 3} B := make([]int, 3) copy(B, A) C := make([]int, 2) copy(C, A) fmt.Println(A, B, C)

Salida:

[1 2 3] [1 2 3] [1 2]

Puede inicializar y copiar todos los elementos en una línea usando append () a un segmento nulo.

x := append([]T{}, []...)

Ejemplo:

A := []int{1, 2, 3} B := append([]int{}, A...) C := append([]int{}, A[:2]...) fmt.Println(A, B, C)

Salida:

[1 2 3] [1 2 3] [1 2]

Comparando con asignación + copia (), para más de 1,000 elementos, use append. En realidad, por debajo de 1,000, la diferencia puede ser descuidada, hazlo como regla general a menos que tengas muchas rebanadas.

BenchmarkCopy1-4 50000000 27.0 ns/op BenchmarkCopy10-4 30000000 53.3 ns/op BenchmarkCopy100-4 10000000 229 ns/op BenchmarkCopy1000-4 1000000 1942 ns/op BenchmarkCopy10000-4 100000 18009 ns/op BenchmarkCopy100000-4 10000 220113 ns/op BenchmarkCopy1000000-4 1000 2028157 ns/op BenchmarkCopy10000000-4 100 15323924 ns/op BenchmarkCopy100000000-4 1 1200488116 ns/op BenchmarkAppend1-4 50000000 34.2 ns/op BenchmarkAppend10-4 20000000 60.0 ns/op BenchmarkAppend100-4 5000000 240 ns/op BenchmarkAppend1000-4 1000000 1832 ns/op BenchmarkAppend10000-4 100000 13378 ns/op BenchmarkAppend100000-4 10000 142397 ns/op BenchmarkAppend1000000-4 2000 1053891 ns/op BenchmarkAppend10000000-4 200 9500541 ns/op BenchmarkAppend100000000-4 20 176361861 ns/op


Otra forma simple de hacer esto es mediante el uso de append que asignará el segmento en el proceso.

arr := []int{1, 2, 3} tmp := append([]int(nil), arr...) // Notice the ... splat fmt.Println(tmp) fmt.Println(arr)

Salida (como se esperaba):

[1 2 3] [1 2 3]

Entonces, una abreviatura para copiar el arreglo arr sería append([]int(nil), arr...)

https://play.golang.org/p/sr_4ofs5GW


Si sus rebanadas fueran del mismo tamaño, funcionaría :

arr := []int{1, 2, 3} tmp := []int{0, 0, 0} i := copy(tmp, arr) fmt.Println(i) fmt.Println(tmp) fmt.Println(arr)

Daría:

3 [1 2 3] [1 2 3]

De " Go Slices: uso y aspectos internos ":

La función de copia admite la copia entre sectores de diferentes longitudes ( copiará solo hasta el menor número de elementos )

El ejemplo habitual es:

t := make([]byte, len(s), (cap(s)+1)*2) copy(t, s) s = t