为什么编译器不警告错误的格式化程序? 在编程中,格式化程序是一种用于美化代码的工具。它可以自动调整代码的缩进、空格、换行等,使代码更易读。然而,有时候我们可能会犯一些格式化程序的错误,比如缺少括号、多余的分号等。尽管这些错误可能会导致代码逻辑上的错误,但编译器却往往不会对这些错误进行警告。那么,为什么编译器不会警告这些错误的格式化程序呢? 首先,编译器的主要任务是将源代码转换为可执行的机器代码,它会对语法错误进行检查,以确保代码的正确性。然而,格式化程序的错误往往是一种语义上的错误,而不是语法上的错误。换句话说,这些错误并不影响代码的可执行性,只是使代码的可读性变差。因此,编译器没有义务去警告这些错误。 其次,格式化程序的错误通常是主观的,不同的开发人员有不同的编码风格和偏好。例如,有些人喜欢在代码中使用大括号,而有些人则不喜欢使用大括号。编译器无法确定哪种风格是正确的,因此也就无法对格式化程序的错误进行警告。 最后,警告格式化程序的错误可能会产生大量的误报。在大型项目中,代码的规模往往非常庞大,一个小小的格式化程序错误可能会导致成千上万的警告。这不仅会对开发人员造成困扰,也会增加代码维护的难度。为了避免这
问题内容
我预计以下代码至少会在编译期间发出警告,因为格式化程序与变量的类型不一致:
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
类型是错误的(但仅在运行时)
解决方法
fmt.printf
格式字符串参数在运行时解释,而不是编译时。
func printf(format string, a ...any) (n int, err error)
printf 根据格式说明符进行格式化并写入标准输出。它返回写入的字节数以及遇到的任何写入错误。
使用静态分析 linter,例如 go vet
。
go 命令 - cmd/go - go 包
报告包中可能存在的错误
用法:
go vet [-n] [-x] [-vettool prog] [build flags] [vet flags] [packages]
vet 对导入路径命名的包运行 go vet 命令。
有关 vet 及其标志的更多信息,请参阅“go doc cmd/vet”。
so.go:
package main
import "fmt"
func main() {
s := "hello"
fmt.printf("1 %wn", s)
fmt.printf("2 %sn", s)
}
短绒检查:
$ 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
$
运行时:
$ go run so.go
1 %!w(string=hello)
2 hello
$