Tengo curiosidad por qué Go no se convierte implícitamente []Ta []interface{}cuándo se convertirá implícitamente Ta interface{}. ¿Hay algo no trivial en esta conversión que me estoy perdiendo?
Ejemplo:
func foo([]interface{}) { /* do something */ }
func main() {
var a []string = []string{"hello", "world"}
foo(a)
}
go build se queja
no puede usar una (cadena de tipo []) como interfaz de tipo [] {} en el argumento de la función
Y si trato de hacerlo explícitamente, lo mismo: se b := []interface{}(a)queja
no puede convertir una (cadena de tipo []) a la interfaz de tipo [] {}
Entonces, cada vez que necesito hacer esta conversión (que parece surgir mucho), he estado haciendo algo como esto:
b = make([]interface{}, len(a), len(a))
for i := range a {
b[i] = a[i]
}
¿Hay una mejor manera de hacer esto, o funciones de biblioteca estándar para ayudar con estas conversiones? Parece un poco tonto escribir 4 líneas adicionales de código cada vez que quiero llamar a una función que puede tomar una lista de, por ejemplo, ints o cadenas.
fuente

Respuestas:
En Go, hay una regla general de que la sintaxis no debe ocultar operaciones complejas / costosas. La conversión de a
stringainterface{}se realiza en tiempo O (1). La conversión de a[]stringainterface{}también se realiza en tiempo O (1) ya que un segmento sigue siendo un valor. Sin embargo, la conversión de a[]stringa[]interface{}es tiempo O (n) porque cada elemento del segmento debe convertirse a aninterface{}.La única excepción a esta regla es convertir cadenas. Al convertir un ay
stringdesde a[]byteo a[]rune, Go funciona O (n) a pesar de que las conversiones son "sintaxis".No hay una función de biblioteca estándar que haga esta conversión por usted. Podrías hacer uno con reflect, pero sería más lento que la opción de tres líneas.
Ejemplo con reflexión:
Sin embargo, su mejor opción es usar las líneas de código que proporcionó en su pregunta:
fuente
maps también por cierto.channelstambién.Converting a []string to an interface{} is also done in O(1) time?Lo que falta es eso
Tyinterface{}que tiene el valor deTtener diferentes representaciones en la memoria, por lo que no se puede convertir trivialmente.Una variable de tipo
Tes solo su valor en la memoria. No hay información de tipo asociada (en Go, cada variable tiene un solo tipo conocido en tiempo de compilación, no en tiempo de ejecución). Se representa en la memoria de esta manera:Una
interface{}celebración de una variable de tipoTse representa en la memoria de esta maneraTVolviendo a su pregunta original: ¿por qué ir no se convierte implícitamente
[]Ta[]interface{}?La conversión
[]Ta[]interface{}implicaría crear una nueva porción deinterface {}valores que es una operación no trivial ya que el diseño en memoria es completamente diferente.fuente
Aquí está la explicación oficial: https://github.com/golang/go/wiki/InterfaceSlice
fuente
[]interfaceal tipo que espero como[]map[string]interface{}?Intenta en su
interface{}lugar. Para lanzar de nuevo como rebanada, intentefuente
barpara interpretarlo como "una porción de cualquier tipo"? Tenga en cuenta que su revestimiento de tres crea un[]interface{}, no[]stringo un trozo de otro tipo de hormigón.func foo(bar []string) { /* ... */ }interface{}hará que el compilador no se queje al pasar un argumento como enfoo(a). Él podría usar el reflejo o el cambio de tipo ( golang.org/doc/effective_go.html#type_switch ) dentrofoo.Convierte
interface{}en cualquier tipo.Sintaxis:
Ejemplo:
fuente
invalid type assertion: potato.([]string) (non-interface type []interface {} on left)En caso de que necesite acortar más su código, puede crear un nuevo tipo para ayudante
luego
fuente