英文:
Why isn't the compiler warning about incorrect formatters?
问题
我原本期望以下代码至少在编译时会引发警告,因为格式化符号与变量的类型不匹配:
package main
import "fmt"
func main() {
s := "hello"
fmt.Printf("1 %w", s)
fmt.Printf("2 %s", s)
}
变量的类型在编译时是已知的,并且字符串格式化符号是以确定性的方式解析的。为什么在这一点上没有引发错误呢?
相反,我得到的输出是:
1 %!w(string=hello)2 hello
这似乎是一种消息,告诉我们 %w
对于类型 string
是错误的(但只在运行时才会出现)。
英文:
I was expecting the following code to at least raise a warning during compilation because the formatters are not aligned with the types of variables:
package main
import "fmt"
func main() {
s := "hello"
fmt.Printf("1 %w", s)
fmt.Printf("2 %s", s)
}
The types of the variables are known at compile time, and the string formatters are parsed in a deterministic way - is there a reason why the error is not raised at that point?
What I get instead is a code that outputs
1 %!w(string=hello)2 hello
This seems to be some kind of message telling that %w
was wrong for the type string
(but only at runtime)
答案1
得分: 3
fmt.Printf
的格式字符串参数是在运行时解释的,而不是编译时。
使用静态分析的linter,例如go vet
。
so.go:
package main
import "fmt"
func main() {
s := "hello"
fmt.Printf("1 %w\n", s)
fmt.Printf("2 %s\n", s)
}
linter:
$ go vet so.go
./so.go:7:2: fmt.Printf 格式 %w 的参数 s 的类型错误,应为 string,
请参阅 https://pkg.go.dev/fmt#hdr-Printing
$
运行时:
$ go run so.go
1 %!w(string=hello)
2 hello
$
英文:
The fmt.Printf
format string argument is interpreted at runtime, not compile time.
> func Printf(format string, a ...any) (n int, err error)
>
> Printf formats according to a format specifier and writes to standard output. It returns the number of bytes written and any write error encountered.
Use a static analysis linter, for example, go vet
.
> go command - cmd/go - Go Packages
>
> Report likely mistakes in packages
>
> Usage:
>
> go vet [-n] [-x] [-vettool prog] [build flags] [vet flags] [packages]
>
> Vet runs the Go vet command on the packages named by the import paths.
>
> For more about vet and its flags, see 'go doc cmd/vet'.
so.go:
package main
import "fmt"
func main() {
s := "hello"
fmt.Printf("1 %w\n", s)
fmt.Printf("2 %s\n", s)
}
linter:
$ go vet so.go
./so.go:7:2: fmt.Printf format %w has arg s of wrong type string,
see also https://pkg.go.dev/fmt#hdr-Printing
$
runtime:
$ go run so.go
1 %!w(string=hello)
2 hello
$
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论