英文:
golang bug with sprintf when giving string as argument to %09d
问题
为什么这段代码没有编译错误?是Go语言的一个错误还是我漏掉了什么?
intPadded := fmt.Sprintf("%09d", "i am a string")
fmt.Println("bah" + intPadded)
执行时输出的结果是:
bah%!d(string=i am a string)
这个问题的原因是你在使用 fmt.Sprintf
函数时,将一个字符串作为格式化参数传递给了 %d
,这个占位符是用来格式化整数的。因此,Go语言会尝试将字符串转换为整数,但是由于字符串无法转换为整数,所以输出结果中会包含一个错误信息 %!d(string=i am a string)
。
要解决这个问题,你需要将 fmt.Sprintf
的格式化参数修改为 %s
,这样就可以正确地将字符串进行格式化了。修改后的代码如下:
intPadded := fmt.Sprintf("%s", "i am a string")
fmt.Println("bah" + intPadded)
执行时输出的结果将会是:
bahi am a string
英文:
Why doesnt this give a compile error, is it a bug in golang or do I miss something?
intPadded := fmt.Sprintf("%09d", "i am a string" )
fmt.Println("bah" + intPadded)
when executed it gives
bah%!d(string=i am a string)
答案1
得分: 2
这是你的错误。编译器只能检查fmt.Sprintf
的参数是否具有正确的类型;所有类型都实现了空接口。你可以使用Go的vet
命令。
func Sprintf(format string, a ...interface{}) string
函数根据格式说明符进行格式化,并返回结果字符串。
接口类型指定了一个称为接口方法集的方法集合。接口类型的变量可以存储具有方法集的任何超集的任何类型的值。这样的类型被称为实现了该接口。
一个类型可以实现包含其方法任意子集的任何接口,因此可以实现多个不同的接口。例如,所有类型都实现了空接口interface{}
。
vet
命令检查Go源代码并报告可疑的结构,例如参数与格式字符串不匹配的Printf调用。
英文:
It's your bug. The compiler can only check that the fmt.Sprintf
arguments have the proper type; all types implement the empty interface. Use the Go vet
command.
> func Sprintf
>
> func Sprintf(format string, a ...interface{}) string
>
> Sprintf formats according to a format specifier and returns the
> resulting string.
>
> Interface types
>
> An interface type specifies a method set called its interface. A
> variable of interface type can store a value of any type with a method
> set that is any superset of the interface. Such a type is said to
> implement the interface.
>
> A type implements any interface comprising any subset of its methods
> and may therefore implement several distinct interfaces. For instance,
> all types implement the empty interface:
>
> interface{}
>
> Command vet
>
> Vet examines Go source code and reports suspicious constructs, such as
> Printf calls whose arguments do not align with the format string.
答案2
得分: 1
如果为动词提供了无效的参数,例如将字符串提供给%d,生成的字符串将包含问题的描述。这是根据http://golang.org/pkg/fmt/中的说明。
它不会在编译时出现错误,因为没有编译时错误。fmt.Sprintf()
被定义为接受...interface{}
作为其最后一个参数,这对于任何类型的序列都是有效的。检查只在运行时进行。
英文:
"If an invalid argument is given for a verb, such as providing a string to %d, the generated string will contain a description of the problem" per http://golang.org/pkg/fmt/
It doesn't give a compile-time error because there is no compile-time error. fmt.Sprintf()
is defined as taking ...interface{}
for its last argument, which is valid for any sequence of types. The checking is done only at runtime.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论