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

Gol*_*den 89 go

我正在使用docopt来解析命令行参数.这是有效的,它会产生一个地图,例如

map[<host>:www.google.de <port>:80 --help:false --version:false]
Run Code Online (Sandbox Code Playgroud)

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

host := arguments["<host>"] + ":" + arguments["<port>"]
Run Code Online (Sandbox Code Playgroud)

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

无效操作:arguments [""] +":"(不匹配的类型interface {}和string)

所以显然我需要将我从地图中得到的值(只是interface{},所以它可以是任何东西)转换为字符串.现在我的问题是,我该怎么做?

Grz*_*Żur 127

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

host := arguments["<host>"].(string) + ":" + arguments["<port>"].(string)
Run Code Online (Sandbox Code Playgroud)

Docopt的最新版本返回选择采用具有用于转换方法的对象:

host, err := arguments.String("<host>")
port, err := arguments.String("<port>")
host_port := host + ":" + port
Run Code Online (Sandbox Code Playgroud)

  • 想补充说这叫做Type Assertion - https://golang.org/ref/spec#Type_assertions.我曾经很难搞清楚这个确切的术语. (7认同)

小智 77

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

hostAndPort := fmt.Sprintf("%v:%v", arguments["<host>"], arguments["<port>"])
Run Code Online (Sandbox Code Playgroud)

  • 对我来说,这不起作用。这最终打印了字节 ASCII 图表而不是字符串,就像 201 变成“[50,48,49]”,所以我最终使用 fmt.Sprintf("%s", theThing) 代替...... (3认同)

jus*_*tan 14

为了扩展Peter所说的内容:由于您希望从接口{}转到字符串,因此键入断言会导致令人头疼,因为您需要考虑多个传入类型.您必须断言每种类型,并在使用之前验证它是否为该类型.

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