如果我有这样的类型:
type myType ...
func (m myType) String() string { ... }
如何使用默认表示法打印(使用各种fmt
函数)此类型(即,而不是调用String()
)?我想做的是这样的事情:
func (m myType) String() string {
// some arbitrary property
if myType.isValid() {
// format properly
} else {
// will recurse infinitely; would like default
// representation instead
return fmt.Sprintf("invalid myType: %v", m)
}
}
答案 0 :(得分:6)
fmt.Stringer
是的默认格式,在您使用%v
时会调用该格式。如果您需要Go语法,请使用%#v
。
或者,您可以完全绕过fmt
中的反射,并根据需要格式化输出。
func (m myType) String() string {
return fmt.Sprintf("{Field: %s}", m.Value)
}
如果myType的基础类型是数字,字符串或其他简单类型,则在打印时转换为基础类型:
func (m mType) String() string {
return fmt.Sprint(int(m))
}
答案 1 :(得分:3)
使用%#v
代替%v
那不会调用String()。 - 但如果你实现它,它将调用GoString()。
答案 2 :(得分:2)
如果您希望让基础类型%#v
正常工作或您的类型是类型别名,则使用String
格式不是正确的答案。
如Effective Go中所述,只需将其转换回它所代表的类型:
type Foo int
func (f Foo) String() string {
if f == 0 {
return "foo"
}
return fmt.Sprintf("%v", int(f)) // N.B.
}
func main() {
fmt.Println(Foo(0))
fmt.Println(Foo(42))
}
编辑:正如其他人在评论中指出的那样,如果您的类型是结构,使用%#v
格式似乎是将其转换为具有相同结构的匿名结构类型的唯一方法字段。