我知道打印int
可以用%d
,string
可以用%s
但是我们仍然可以使用%v
来打印它们.那么,如果我总是使用%v
来打印它们,那又会怎么样呢?如果我这样做会发生什么问题?
我知道打印int
可以用%d
,string
可以用%s
但是我们仍然可以使用%v
来打印它们.那么,如果我总是使用%v
来打印它们,那又会怎么样呢?如果我这样做会发生什么问题?
不会有什么不好的事情发生,但是%d
动词指示fmt
包打印为数字(使用基数10),而%v
动词表示使用可以覆盖的default格式.
请参阅此示例:
type MyInt int
func (mi MyInt) String() string {
return fmt.Sprint("*", int(mi), "*")
}
func main() {
var mi MyInt = 2
fmt.Printf("%d %v", mi, mi)
}
输出(在Go Playground上try ):
2 *2*
当使用%v
谓词时,fmt
包判断该值是否实现了fmt.Stringer
接口(这是一个单独的String() string
方法),如果实现了,将调用该方法将该值转换为string
(如果指定了标志,则可能会进一步格式化).
格式规则的完整列表在fmt
号文件包中,引用了相关部分:
除非使用动词%T和%p打印,否则实现某些接口的操作数需要特殊的格式考虑.按申请顺序:
如果操作数是refect.Value,则操作数将被其保存的具体值替换,并且打印将继续执行下一个规则.
如果操作数实现格式化程序接口,则将调用该操作数.格式化程序提供了对格式化的精细控制.
如果%v谓词与#标志(%#v)一起使用,并且操作数实现了GoStringer接口,则将调用该接口.
如果格式(对于Println等隐式为%v)对于字符串(%s%Q%v%x%X)有效,则适用以下两条规则:
如果操作数实现了Error接口,则将调用Error方法将对象转换为字符串,然后按照谓词(如果有)所需的格式设置该字符串的格式.
如果操作数实现方法string()string,将调用该方法将对象转换为字符串,然后按照谓词(如果有的话)的要求格式化该字符串.