我正在使用docopt来解析命令行参数。这是有效的,它会产生一个地图,例如
map[<host>:www.google.de <port>:80 --help:false --version:false]
现在我想将host
和port
值连接到两个值之间带冒号的字符串。基本上,如:
host := arguments["<host>"] + ":" + arguments["<port>"]
不幸的是,这不起作用,因为我收到错误消息:
无效操作:arguments [“”] +“:”(不匹配类型interface {}和string)
所以显然我需要将我从地图中获得的值(只是interface{}
,因此它可以是任何东西)转换为字符串。现在我的问题是,我该怎么做?
答案 0 :(得分:112)
您需要添加type assertion .(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
答案 1 :(得分:68)
您不需要使用类型断言,而只需将%v
格式说明符与Sprintf
一起使用:
hostAndPort := fmt.Sprintf("%v:%v", arguments["<host>"], arguments["<port>"])
答案 2 :(得分:13)
扩大彼得所说的话: 由于您希望从接口{}转到字符串,因此类型断言将导致令人头疼,因为您需要考虑多个传入类型。您必须断言每种类型,并在使用之前验证它是否为该类型。
使用fmt.Sprintf(https://golang.org/pkg/fmt/#Sprintf)自动处理接口转换。由于您知道所需的输出类型始终是一个字符串,因此Sprintf将处理接口背后的任何类型,而无需代表您使用大量额外代码。
答案 3 :(得分:0)
您也可以使用 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")
}