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

我使用 Docopt来解析命令行参数

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

现在,我想将 hostport值连接到一个字符串,在这两个值之间加一个冒号。基本上是这样的:

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

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

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

所以很明显,我需要将我从 map (只是 interface{},因此它可以是任何值)得到的值转换成一个字符串。现在我的问题是,我该怎么做?

226507 次浏览

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

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

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

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

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

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

详细说明彼得说过的话: 由于您希望从接口{}转换为字符串,因此类型断言将导致令人头疼的问题,因为您需要考虑多个传入类型。在使用之前,必须尽可能地断言每种类型并验证它是否为该类型。

使用 fmt。Sprintf (https://golang.org/pkg/fmt/#Sprintf)自动处理接口转换。因为你知道你想要的输出类型总是一个字符串,Sprintf 将处理界面后面的任何类型,而不需要一堆额外的代码。

你也可以使用 text/template:

package main


import (
"text/template"
"strings"
)


func format(s string, v interface{}) string {
t, b := new(template.Template), new(strings.Builder)
template.Must(t.Parse(s)).Execute(b, v)
return b.String()
}


func main() {
m := map[string]interface{}{"<host>": "www.google.de", "<port>": "80"}
s := format(`\{\{index . "<host>"}}:\{\{index . "<port>"}}`, m)
println(s == "www.google.de:80")
}

Https://pkg.go.dev/text/template