英文:
Why can we have unused functions but we can't have unused variables?
问题
未使用的变量会阻止编译(这是一件好事),但编译器对未使用的函数并不真正关心,这是为什么呢?
英文:
Unused variables will block compiling (that's a good thing) but compiler don't really care about unused functions, is there an explanation ?
答案1
得分: 2
行为在变量和函数之间似乎是一致的 - 即使未使用,两者都允许在包级作用域中。
这段代码在没有任何问题的情况下编译通过:
package main
var v int // 未使用的变量
func f() {} // 未使用的函数
func main() {}
现在,当涉及到局部作用域时情况就不同了,未使用的变量会生成错误。对于函数字面量也是如此(在Go中不允许使用命名的嵌套函数):
func main() {
func() {}
}
// 错误:函数字面量被计算但未使用
最后,为什么只检查局部作用域中的未使用变量?因为通常这是一个错误(例如,在Go中,由于意外使用了:=
)。编译器在这里帮了我很多次。考虑以下情况:
func f() (err error) {
if somthing {
err := g() // err 是未使用的变量!我真正想要的是 `=`
}
return
}
对于全局(包级)作用域,未使用的变量和函数通常只是污染命名空间,例如,有人在重构后忘记删除它们。有一些工具可以帮助检测这些问题,例如:
- https://github.com/opennota/check
- https://github.com/alecthomas/gometalinter(使用上述包)
- https://github.com/remyoudompheng/go-misc/blob/master/deadcode/deadcode.go
我还找到了 Russ Cox 的一篇帖子对此问题进行了评论:
> 最近我用 gcc -Wall -Werror 写了一些 C 代码。当你只是想测试你已经完成的代码或注释掉可能引起问题的调用时,这使得原型代码有些困难。当然,对于未使用的局部变量发出警告也是一样的。不同之处在于,在 Go 中,由于 :=
,未使用的局部变量很常见是一个 bug,而未使用的未导出函数很少是一个 bug。
>
> Russ
英文:
The behaviour seems consistent between variables and functions – both are allowed in a package-level scope, even if unused.
This snippet is compiling without any issues:
package main
var v int // unused variable
func f() {} // unused function
func main() {}
Now, when it comes to local scope things are different and unused variables generate errors. Same for function literals (named nested functions are not allowed in Go):
func main() {
func() {}
}
// Error: func literal evaluated but not used
Finally, why is only local scope checked for unused variables? Because usually it's a bug (for examples, in Go, due to an accidental usage of :=
). And compiler saved me many times here. Consider this:
func f() (err error) {
if somthing {
err := g() // err is unused variable! I really meant `=`.
}
return
}
For global (package-level) scopes unused variables and functions are usually just polluting the namespace as, for example, someone forgot to remove them after refactoring. There're some tools which helps detecting these, for example:
- https://github.com/opennota/check
- https://github.com/alecthomas/gometalinter (uses the previous package)
- https://github.com/remyoudompheng/go-misc/blob/master/deadcode/deadcode.go
I also found a post by Russ Cox commenting on the issue:
> I have been writing some C code with gcc -Wall -Werror recently. It
> makes prototyping code somewhat difficult to be told "you didn't use
> that function, go fix it" when you're just trying to test what you've
> got so far, or commenting out calls that are possibly causing trouble.
> Of course the same is true for warning about unused local variables
> too. The difference is that, in Go, because of :=, an unused local
> variable is very often a bug, while an unused unexported function is
> much less often a bug.
>
> Russ
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论