¿Cómo convertir la interfaz {} en cadena?

114

Estoy usando docopt para analizar los argumentos de la línea de comandos. Esto funciona y da como resultado un mapa, como

map[<host>:www.google.de <port>:80 --help:false --version:false]

Ahora me gustaría concatenar el hosty el portvalor a una cadena con dos puntos entre los dos valores. Básicamente, algo como:

host := arguments["<host>"] + ":" + arguments["<port>"]

Desafortunadamente, esto no funciona, ya que recibo el mensaje de error:

operación no válida: argumentos [""] + ":" (tipos no coincidentes interfaz {} y cadena)

Entonces, obviamente, necesito convertir el valor que obtengo del mapa (que es solo interface{}, por lo que puede ser cualquier cosa) en una cadena. Ahora mi pregunta es, ¿cómo hago eso?

Golo Roden
fuente

Respuestas:

153

Debe agregar una afirmación de tipo .(string) . Es necesario porque el mapa es de tipo map[string]interface{}:

host := arguments["<host>"].(string) + ":" + arguments["<port>"].(string)

La última versión de Docopt devuelve el objeto Opts que tiene métodos para la conversión:

host, err := arguments.String("<host>")
port, err := arguments.String("<port>")
host_port := host + ":" + port
Grzegorz Żur
fuente
7
Me gustaría agregar que esto se llama Aserción de tipo: golang.org/ref/spec#Type_assertions . Una vez tuve problemas para descifrar esta terminología exacta.
Sreejith Ramakrishnan
Causará
89

No es necesario utilizar una aserción de tipo, en su lugar, utilice el %vespecificador de formato con Sprintf:

hostAndPort := fmt.Sprintf("%v:%v", arguments["<host>"], arguments["<port>"])
Peter Stace
fuente
Esto fue lo único que pude hacer para mí cuando intentaba escribir interfaces de transmisión {} con as cadenas.
FilBot3
1
Para mí, esto no funcionó. Esto terminó imprimiendo los gráficos ASCII de bytes en lugar de la cadena, como 201 se convirtió en "[50,48,49]", así que terminé usando fmt.Sprintf ("% s", theThing) en su lugar ...
Felipe Valdes
18

Para ampliar lo que dijo Peter: ya que está buscando pasar de la interfaz {} a la cadena, la aserción de tipos le dará dolores de cabeza, ya que debe tener en cuenta varios tipos entrantes. Tendrá que afirmar cada tipo posible y verificar que sea ese tipo antes de usarlo.

El uso de fmt.Sprintf ( https://golang.org/pkg/fmt/#Sprintf ) maneja automáticamente la conversión de la interfaz. Como sabe que el tipo de salida deseado es siempre una cadena, Sprintf manejará cualquier tipo que esté detrás de la interfaz sin un montón de código adicional en su nombre.

justitan
fuente