Como converter interface {} em string?

114

Estou usando docopt para analisar argumentos de linha de comando. Isso funciona e resulta em um mapa, como

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

Agora, eu gostaria de concatenar o hoste o portvalor em uma string com dois pontos entre os dois valores. Basicamente, algo como:

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

Infelizmente, isso não funciona, pois recebo a mensagem de erro:

operação inválida: argumentos [""] + ":" (interface de tipos incompatíveis {} e string)

Obviamente, preciso converter o valor que obtenho do mapa (que é justo interface{}, então pode ser qualquer coisa) em uma string. Agora, minha pergunta é: como faço isso?

Golo Roden
fonte

Respostas:

153

Você precisa adicionar a asserção de tipo .(string) . É necessário porque o mapa é do tipo map[string]interface{}:

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

A última versão do Docopt retorna o objeto Opts que possui métodos de conversão:

host, err := arguments.String("<host>")
port, err := arguments.String("<port>")
host_port := host + ":" + port
Grzegorz Żur
fonte
7
Gostaria de acrescentar que isso é chamado de Asserção de Tipo - golang.org/ref/spec#Type_assertions . Certa vez, tive problemas para descobrir essa terminologia exata.
Sreejith Ramakrishnan,
Irá causar pânico se os argumentos ["<host>"] for nulo
Savash
89

Você não precisa usar uma asserção de tipo, em vez disso, apenas use o %vespecificador de formato com Sprintf:

hostAndPort := fmt.Sprintf("%v:%v", arguments["<host>"], arguments["<port>"])
Peter Stace
fonte
Isso foi a única coisa que consegui fazer funcionar para mim ao tentar digitar interfaces cast {} como strings.
FilBot3
1
Para mim, isso não funcionou. Isso acabou imprimindo os gráficos ASCII de bytes em vez da string, como 201 se tornou "[50,48,49]", então acabei usando fmt.Sprintf ("% s", theThing) em vez ...
Felipe Valdes
18

Para expandir o que Peter disse: Já que você está procurando ir da interface {} para a string, a asserção de tipo levará a dores de cabeça, pois você precisa levar em conta vários tipos de entrada. Você terá que declarar cada tipo possível e verificar se é aquele tipo antes de usá-lo.

Usar fmt.Sprintf ( https://golang.org/pkg/fmt/#Sprintf ) controla automaticamente a conversão da interface. Como você sabe que o tipo de saída desejado é sempre uma string, Sprintf irá lidar com qualquer tipo que esteja por trás da interface sem um monte de código extra em seu nome.

Justitan
fonte