当将字符串作为参数传递给`%09d`时,Golang中的`sprintf`存在bug。

huangapple go评论109阅读模式
英文:

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调用。

func Sprintf

Interface types

Command vet

英文:

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.

huangapple
  • 本文由 发表于 2014年3月30日 21:05:25
  • 转载请务必保留本文链接:https://go.coder-hub.com/22744328.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定