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

时间:2014-11-25 21:58:24

标签: go

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

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

现在我想将hostport值连接到两个值之间带冒号的字符串。基本上,如:

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

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

  

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

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

4 个答案:

答案 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")
}

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