我正在学习 Go,但我觉得编译时有点烦人,我不应该留下任何未使用的变量或包。
这真的让我慢了下来。例如,我只想声明一个新包并计划稍后使用它,或者只是取消注释某些命令以进行测试。我总是收到错误,需要评论所有这些用途。
有什么办法可以避免这种在 Go 中的检查吗?
_
仍然是一项非常繁琐的工作,显然会破坏开发人员的流程。每次您注释掉某些内容时,您都需要去存根所有 declared but not used
错误。任何团队都可以将标准和样式检查作为提交挂钩或 CI/Gate 工作的一部分来实施。这里缺乏给开发人员的代理权是一种傲慢,而且还迫使我们编写 worse 代码以便能够将事情分开。 goimports
解决了导入问题,变量应该可以接受编译器标志。
该错误会迫使您编写更好的代码,并确保使用您声明或导入的所有内容。它使阅读其他人编写的代码变得更容易(您始终确信所有声明的变量都会被使用),并避免一些可能的死代码。
但是,如果你真的想跳过这个错误,你可以使用 blank identifier (_
) :
package main
import (
"fmt" // imported and not used: "fmt"
)
func main() {
i := 1 // i declared and not used
}
变成
package main
import (
_ "fmt" // no more error
)
func main() {
i := 1 // no more error
_ = i
}
正如 kostix 在下面的评论中所说,您可以找到 Go 团队 in the FAQ 的官方立场:
未使用变量的存在可能表明存在错误,而未使用的导入只会减慢编译速度。在你的代码树中积累足够多的未使用的导入,事情会变得非常缓慢。由于这些原因,Go 两者都不允许。
您可以为此使用简单的“空函数”,例如:
func Use(vals ...interface{}) {
for _, val := range vals {
_ = val
}
}
您可以像这样使用它:
package main
func main() {
a := "declared and not used"
b := "another declared and not used"
c := 123
Use(a, b, c)
}
有 also a package for this,因此您不必每次都定义 Use
函数:
import (
"github.com/lunux2008/xulu"
)
func main() {
// [..]
xulu.Use(a, b, c)
}
根据the FAQ:
有些人要求提供编译器选项来关闭这些检查或至少将它们减少为警告。但是,没有添加这样的选项,因为编译器选项不应该影响语言的语义,并且因为 Go 编译器不报告警告,只报告阻止编译的错误。没有警告有两个原因。首先,如果值得抱怨,那就值得在代码中修复。 (如果它不值得修复,那就不值得一提。)其次,让编译器生成警告鼓励实现警告可能使编译嘈杂的弱案例,掩盖应该修复的真正错误。
由于各种不值得讨论的原因,我不一定同意这一点。它就是这样,在不久的将来不太可能改变。
对于包,goimports
工具会自动添加丢失的包并删除未使用的包。例如:
# Install it
$ go get golang.org/x/tools/cmd/goimports
# -w to write the source file instead of stdout
$ goimports -w my_file.go
您应该能够从任何中途体面的编辑器运行它 - 例如对于 Vim:
:!goimports -w %
goimports
页面列出了其他编辑器的一些命令,您通常将其设置为在将缓冲区保存到磁盘时自动运行。
请注意,goimports
也将运行 gofmt
。
如前所述,对于变量,最简单的方法是(暂时)将它们分配给 _
:
// No errors
tasty := "ice cream"
horrible := "marmite"
// Commented out for debugging
//eat(tasty, horrible)
_, _ = tasty, horrible
两年前我在学习 Go 时遇到了这个问题,所以我声明了自己的函数。
// UNUSED allows unused variables to be included in Go programs
func UNUSED(x ...interface{}) {}
然后你可以像这样使用它:
UNUSED(x)
UNUSED(x, y)
UNUSED(x, y, z)
它的好处是,你可以将任何东西传递给 UNUSED。
是不是比下面的好?
_, _, _ = x, y, z
这取决于你。
如果其他人很难理解这一点,我认为用非常简单的术语解释它可能会有所帮助。如果你有一个不使用的变量,例如一个你已经注释掉调用的函数(一个常见的用例):
myFn := func () { }
// myFn()
您可以为函数分配一个无用/空白变量,使其不再被使用:
myFn := func () { }
_ = myFn
// myFn()
到目前为止没有提到的一个角度是用于编辑代码的工具集。
使用 Visual Studio Code 以及来自 lukehoban 的名为 Go
的扩展程序将为您带来一些自动魔法。 Go 扩展程序会自动运行 gofmt
、golint
等,并删除和添加 import
个条目。所以至少那部分现在是自动的。
我承认它不是问题的 100% 的解决方案,但它足够有用。
当我想在处理代码的另一部分时暂时禁用发送电子邮件时遇到了这个问题。
评论服务的使用触发了很多级联错误,所以我没有评论我使用了一个条件
if false {
// Technically, svc still be used so no yelling
_, err = svc.SendRawEmail(input)
Check(err)
}