Golang中build和test命令的对比与使用

Golang中build和test命令的对比与使用 我是Go语言的新手。有人能解释为什么"go build"没有捕获下面代码中的编译错误,而"go test"却捕获到了吗?

package main

import (
"fmt"
)

func main() {
i := 10
fmt.Println("%d", i)
}

go test ./hello_world.go:9:2: Println call has possible formatting directive %d

这个错误是预期的。然而,“go build"没有给出任何错误。 我原本期望"go test"会先执行"go build”,然后再运行测试(在这个例子中没有测试)。


更多关于Golang中build和test命令的对比与使用的实战教程也可以访问 https://www.itying.com/category-94-b0.html

3 回复

我的问题与运行测试无关。问题是为什么"go build"没有捕获上述代码块中明显的编译警告。

更多关于Golang中build和test命令的对比与使用的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html


首先,让我们在论坛中正确引用这段代码:

package main

import (
        "fmt"
)

func main() {
        i := 10
        fmt.Println("%d", i)
}

然后也把它放到Go Playground中:

https://play.golang.org/p/9fLRBaLqojx

点击那里的运行按钮,你会看到与运行go test时相同的错误。这是因为Go Playground在编译代码之前会运行go vet

go test也是如此。你可以使用-vet=off选项来禁用这个功能:

go test -vet=off main.go

你可以单独运行go vet来只获取警告。

关于这个警告,你可能想要的是:

fmt.Println(i)

或者

fmt.Printf("%d\n",i)

在Go语言中,go buildgo test命令在代码检查方面确实存在差异,这主要是由于它们的设计目的不同。

go build命令专注于将Go代码编译成可执行文件或包,默认情况下它不会执行vet工具(用于静态分析代码中的可疑构造)。而go test命令在运行测试时会自动执行go vet,这能捕获到代码中的潜在问题,比如格式字符串错误。

在你的代码示例中:

package main

import (
    "fmt"
)

func main() {
    i := 10
    fmt.Println("%d", i)  // 错误:Println不需要格式字符串
}

fmt.Println函数设计为直接输出参数,不需要格式字符串。正确的用法应该是:

fmt.Println(i)  // 直接输出变量值

或者使用格式化输出:

fmt.Printf("%d\n", i)  // 使用Printf进行格式化输出

go test捕获到这个错误是因为它自动运行了vet检查,而go build默认不会。

如果你希望在构建时也进行类似的检查,可以显式运行vet:

go vet

或者将构建和vet检查结合:

go build -vet

从Go 1.10开始,go test命令默认会运行vet,但可以通过-vet=off禁用:

go test -vet=off

这种设计差异使得测试环境能够提供更严格的代码质量检查,帮助开发者在早期发现潜在问题。

回到顶部