Para declarar un segmento vacío, con un tamaño no fijo, es mejor hacerlo:
mySlice1 := make([]int, 0)
o:
mySlice2 := []int{}
Solo me pregunto cuál es la forma correcta.
Para declarar un segmento vacío, con un tamaño no fijo, es mejor hacerlo:
mySlice1 := make([]int, 0)
o:
mySlice2 := []int{}
Solo me pregunto cuál es la forma correcta.
Respuestas:
Las dos alternativas que proporcionó son semánticamente idénticas, pero el uso make([]int, 0)
dará como resultado una llamada interna a runtime.makeslice (Ir 1.14).
También tiene la opción de dejarlo con un nil
valor:
var myslice []int
Como está escrito en el blog Golang.org :
un corte nulo es funcionalmente equivalente a un corte de longitud cero, aunque no apunta a nada. Tiene longitud cero y se puede agregar, con asignación.
Una nil
rebanada será sin embargo json.Marshal()
en "null"
mientras que una rebanada vacía formar en "[]"
, como fuera puntiagudo por @farwayer.
Ninguna de las opciones anteriores causará ninguna asignación, como lo señaló @ArmanOrdookhani.
json.Marshal()
regresará null
por var myslice []int
y []
para el segmento inicializadomyslice := []int{}
reflect.DeepEqual
hace una distinción entre las rebanadas nil y rodajas no nulos: a := []int{}
, var b []int
,reflect.DeepEqual(a, b) // returns false
Son equivalentes Ver este código:
mySlice1 := make([]int, 0)
mySlice2 := []int{}
fmt.Println("mySlice1", cap(mySlice1))
fmt.Println("mySlice2", cap(mySlice2))
Salida:
mySlice1 0
mySlice2 0
Ambas rebanadas tienen 0
capacidad, lo que implica que ambas tienen 0
longitud (no puede ser mayor que la capacidad), lo que implica que ambas rebanadas no tienen elementos. Esto significa que las 2 rebanadas son idénticas en todos los aspectos.
Ver preguntas similares:
¿Cuál es el punto de tener una rebanada nula y una rebanada vacía en golang?
Como una adición a la respuesta de @ANisus ...
a continuación hay información del libro "Go in action" , que creo que vale la pena mencionar:
nil
y empty
rebanadasSi pensamos en una rebanada como esta:
[pointer] [length] [capacity]
luego:
nil slice: [nil][0][0]
empty slice: [addr][0][0] // points to an address
rebanada nula
Son útiles cuando desea representar un segmento que no existe, como cuando ocurre una excepción en una función que devuelve un segmento.
// Create a nil slice of integers. var slice []int
rebanada vacía
Los sectores vacíos son útiles cuando desea representar una colección vacía, como cuando una consulta de base de datos devuelve cero resultados.
// Use make to create an empty slice of integers. slice := make([]int, 0) // Use a slice literal to create an empty slice of integers. slice := []int{}
Independientemente de si usted está utilizando una rebanada nula o una rodaja de vacío, la incorporada en funciones
append
,len
ycap
funcionan de la misma.
Vaya ejemplo de patio de recreo :
package main
import (
"fmt"
)
func main() {
var nil_slice []int
var empty_slice = []int{}
fmt.Println(nil_slice == nil, len(nil_slice), cap(nil_slice))
fmt.Println(empty_slice == nil, len(empty_slice), cap(empty_slice))
}
huellas dactilares:
true 0 0
false 0 0
make
?
La división vacía y la división nula se inicializan de manera diferente en Ir:
var nilSlice []int
emptySlice1 := make([]int, 0)
emptySlice2 := []int{}
fmt.Println(nilSlice == nil) // true
fmt.Println(emptySlice1 == nil) // false
fmt.Println(emptySlice2 == nil) // false
En cuanto a las tres rebanadas, len y cap son 0.
make([]int, 0)
es lo mejor porque Jetbrains GoLand no se queja de que sea "innecesario" como lo hace en el caso de []int{}
. Esto es útil para escribir pruebas unitarias.
keys := make([]int, 0, len(m)); for k, v := range m { keys := append(keys,k) }