如何将interface {}转换为字符串?


114

我正在使用docopt来解析命令行参数。这样行之有效,并生成一张地图,例如

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

现在,我想将hostport值连接到一个字符串,并在两个值之间插入一个冒号。基本上,诸如:

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

不幸的是,这不起作用,因为我收到了错误消息:

无效的操作:arguments [“”] +“:”(类型不匹配的接口{}和字符串)

因此,显然我需要将从映射中获取的值(就是interface{},所以可以是任意值)转换为字符串。现在我的问题是,我该怎么做?


Answers:


153

您需要添加类型断言 .(string)。这是必需的,因为地图的类型是map[string]interface{}

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

Docopt的最新版本返回OPTS对象,对转换方法:

host, err := arguments.String("<host>")
port, err := arguments.String("<port>")
host_port := host + ":" + port

7
想补充一点,这就是所谓的类型断言- golang.org/ref/spec#Type_assertions。我曾经很难弄清楚这个确切的术语。
Sreejith Ramakrishnan

如果arguments [“ <host>”]为nil,则会引起恐慌
Savash

89

您不需要使用类型断言,而只需将%v格式说明符与一起使用Sprintf

hostAndPort := fmt.Sprintf("%v:%v", arguments["<host>"], arguments["<port>"])

这是我尝试以字符串形式输入强制转换接口{}时唯一能为我工作的东西。
FilBot3

1
对我来说,这行不通。这样最终打印出了字节ASCII图表而不是字符串,就像201变成了[[50,48,49]”,所以我最终使用了fmt.Sprintf(“%s”,theThing)代替...
Felipe Valdes

18

扩展一下Peter所说的内容:由于您希望从interface {}转换为字符串,因此类型断言将导致头痛,因为您需要考虑多种传入类型。您必须断言每种可能的类型,并在使用前确认它是该类型。

使用fmt.Sprintf(https://golang.org/pkg/fmt/#Sprintf)自动处理接口转换。由于您知道所需的输出类型始终是字符串,因此Sprintf可以处理接口后面的任何类型,而无需代表您一堆额外的代码。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.