array - golang size
¿Por qué no puedo duplicar un segmento con `copy()` en Golang? (5)
La especificación del lenguaje de programación Go
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)
ylen(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...)
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