在 Go 中,为什么在转换为字符串时不使用 stringer 接口?

In Go, why isn't the stringer interface used when casting to string?

package main

type foo struct {
    bar string
    baz string
}

func (f foo) String() string {
    return f.bar + " " + f.baz
}

func main() {
    f := foo{"hello", "world"}
    v := string(f)
}

这输出 main.go:14: cannot convert f (type foo) to type string.

因此,将某些内容转换为字符串似乎不会查看 stinger 接口。我的猜测是,这是因为转换是在比 stringer 接口更低的级别上实现的,并且将两者混合是 impossible/hard,但我不确定。任何人都可以阐明这一点吗?

此外,由于这是不可能的,在这种情况下,将我的结构转换为字符串的惯用方法是什么?我是直接给自己打电话 .String(),还是 fmt.Sprintf("%s", f),或者别的什么?

Go中没有casting,有类型Conversion and Type assertion.

您正在做的 (T(Expression)) 是一种转换,它在何时可以使用以及结果如何方面有严格的规定。

有适用于 Conversions to and from a string type 的特定规则。所以你想要的是类型转换无法实现的。

最简单和首选的方法是自己调用该方法:

v := f.String()
如果您的

fmt.Sprintf() 已经实现了 Stringer,那么

fmt.Sprintf() 只是不必要的开销和复杂化。但是,如果您对此没有保证,那么是的,fmt.Sprintf() 将是一般方式。

你可以问为什么?

在规范级别中,类型转换表达式未定义为 custom/user 生成的函数或方法的结果。与 error 接口相比,Stringer 接口 (type Stringer interface{String() string}) 甚至不是内置类型。

但是尽管 Stringer 不是内置类型,它仍然存在于某些包中(例如在 fmt.Stringer) and is checked by various methods or functions (e.g. fmt.Printf() 和亲戚中)。