type pointer golang datatypes cast type-conversion go

type-conversion - pointer - golang type



No se puede convertir[] cadena a[] interfaz{} (5)

En Go, una función solo puede aceptar argumentos de los tipos especificados en la lista de parámetros en la definición de la función. La característica de lenguaje de parámetros variados lo complica un poco, pero sigue reglas bien definidas.

La firma de la función para fmt.Println es:

func Println(a ...interface{}) (n int, err error)

Según la especificación del idioma ,

El parámetro entrante final en una firma de función puede tener un tipo prefijado ... Una función con dicho parámetro se denomina variadic y se puede invocar con cero o más argumentos para ese parámetro.

Esto significa que puede pasarle a Println una lista de argumentos de la interface{} . Dado que todos los tipos implementan la interfaz vacía, puede pasar una lista de argumentos de cualquier tipo, que es cómo puede llamar a Println(1, "one", true) , por ejemplo, sin error. Consulte la sección "Pasar argumentos a ... parámetros" de la especificación del lenguaje:

el valor pasado es una nueva porción del tipo [] T con una nueva matriz subyacente cuyos elementos sucesivos son los argumentos reales, que todos deben ser asignables a T.

La parte que le está causando problemas es justo después de eso en la especificación:

Si el argumento final es asignable a un tipo de sector [] T, se puede pasar sin cambios como el valor de un parámetro ... T si el argumento es seguido por .... En este caso, no se crea un segmento nuevo.

flag.Args() es una []string tipo []string . Como T en Println es la interface{} , []T es []interface{} . Entonces, la pregunta se reduce a si un valor de corte de cadena se puede asignar a una variable del tipo de corte de interfaz. Puede probarlo fácilmente en su código de ir al intentar una tarea, por ejemplo:

s := []string{} var i []interface{} i = s

Si intenta tal asignación, el compilador generará este mensaje de error:

cannot use s (type []string) as type []interface {} in assignment

Y es por eso que no puede usar la elipsis después de un segmento de cadena como argumento para fmt.Println . No es un error, está funcionando como se esperaba.

Todavía hay muchas formas de imprimir flag.Args() con Println , como

fmt.Println(flag.Args())

(que saldrá como [elem0 elem1 ...] , por la documentación del paquete fmt )

o

fmt.Println(strings.Join(flag.Args(), ` `)

(que generará los elementos del segmento de cadena, cada uno separado por un único espacio) utilizando la función Unir en el paquete de cadenas con un separador de cadenas, por ejemplo.

Estoy escribiendo un código, y necesito capturar los argumentos y pasarlos a través de fmt.Println
(Quiero su comportamiento predeterminado, escribir argumentos separados por espacios y seguidos por una nueva línea). Sin embargo, toma []interface {} pero flag.Args() devuelve una []string .
Aquí está el ejemplo del código:

package main import ( "fmt" "flag" ) func main() { flag.Parse() fmt.Println(flag.Args()...) }

Esto devuelve el siguiente error:

./example.go:10: cannot use args (type []string) as type []interface {} in function argument

¿Es esto un error? ¿No debería fmt.Println tomar cualquier matriz? Por cierto, también he intentado hacer esto:

var args = []interface{}(flag.Args())

pero me sale el siguiente error:

cannot convert flag.Args() (type []string) to type []interface {}

¿Hay alguna manera de "ir" para solucionar esto?


En este caso, una conversión de tipo es innecesaria. Simplemente pase el valor flag.Args() a fmt.Println .

Pregunta:

No se puede convertir [] cadena a [] interfaz {}

Estoy escribiendo un código, y necesito capturar los argumentos y pasarlos a través de fmt.Println (quiero su comportamiento predeterminado, escribir argumentos separados por espacios y seguidos por una nueva línea).

Aquí está el ejemplo del código:

package main import ( "fmt" "flag" ) func main() { flag.Parse() fmt.Println(flag.Args()...) }

Bandera del paquete

import "flag"

func Args

func Args() []string

Args devuelve los argumentos de línea de comandos que no son de Args .

Paquete fmt

import "fmt"

func Println

func Println(a ...interface{}) (n int, err error)

Println formatos usando los formatos predeterminados para sus operandos y escrituras en salida estándar. Los espacios siempre se agregan entre operandos y se agrega una nueva línea. Devuelve el número de bytes escritos y cualquier error de escritura encontrado.

En este caso, una conversión de tipo es innecesaria. Simplemente pase el valor flag.Args() a fmt.Println , que usa la reflexión para interpretar el valor como una []string tipo []string . Package reflect implementa la reflexión en tiempo de ejecución, lo que permite que un programa manipule objetos con tipos arbitrarios. Por ejemplo,

args.go :

package main import ( "flag" "fmt" ) func main() { flag.Parse() fmt.Println(flag.Args()) }

Salida:

$ go build args.go $ ./args arg0 arg1 [arg0 arg1] $


Esto no es un error. fmt.Println() requiere un tipo []interface{} . Eso significa que debe ser una porción de valores de interface{} y no "ningún sector". Para convertir la porción, tendrá que repetir y copiar cada elemento.

old := flag.Args() new := make([]interface{}, len(old)) for i, v := range old { new[i] = v } fmt.Println(new...)

La razón por la que no puede usar ningún segmento es que la conversión entre una []string y una []interface{} requiere que el diseño de la memoria se modifique y ocurra en el tiempo O (n). La conversión de un tipo a una interface{} requiere O (1) tiempo. Si hicieran innecesario este ciclo, el compilador aún tendría que insertarlo.


Si solo desea un segmento de cadenas que desea imprimir, puede evitar la conversión y obtener el mismo resultado uniéndose:

package main import ( "fmt" "flag" "strings" ) func main() { flag.Parse() s := strings.Join(flag.Args(), " ") fmt.Println(s) }


fmt.Println toma el parámetro variad

func Println (a ... interfaz {}) (n int, err error)

Es posible imprimir flag.Args() sin convertir a []interface{}

func main() { flag.Parse() fmt.Println(flag.Args()) }