ChatGPT解决这个技术问题 Extra ChatGPT

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

go

我正在使用 docopt 来解析命令行参数。这行得通,它会产生一张地图,例如

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

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

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

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

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

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

fmt.Sprint(data) // 其中数据是接口{}

G
Grzegorz Żur

您需要添加 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

想补充一点,这称为类型断言 - golang.org/ref/spec#Type_assertions。我曾经很难弄清楚这个确切的术语。
如果 arguments[""] 为 nil 将导致恐慌
P
Peter Stace

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

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

这是我在尝试使用 as 字符串键入 cast interface{} 时唯一可以为我工作的事情。
对我来说,这行不通。这最终打印了字节 ASCII 图表而不是字符串,比如 201 变为“[50,48,49]”,所以我最终使用 fmt.Sprintf("%s", theThing) 代替......
j
justitan

扩展彼得所说的内容:由于您希望从 interface{} 转到字符串,类型断言将导致头疼,因为您需要考虑多种传入类型。您必须声明每种可能的类型并在使用它之前验证它是该类型。

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


Z
Zombo

您也可以使用 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


关注公众号,不定期副业成功案例分享
关注公众号

不定期副业成功案例分享

领先一步获取最新的外包任务吗?

立即订阅