为什么Go编译器不将非声明变量视为错误?

时间:2013-10-13 04:31:45

标签: go

我一直在写一个测试程序来帮助学习Go。在这样做时,我遇到了一些我认为编译器应该检测到错误的实例。我遇到了另一种类似的情况,所以我想我应该问为什么这种情况不会被视为错误。

示例情况:

if oError = rwfile.WriteLines(asParams, sParamsFilename); oError != nil {
    fmt.Printf("Error on write to file Params. Error = %s\n", oError)
} else {
    println("Params file write OK")
}

在上面的示例中,无论是否声明变量“oError”,编译器都不会指示错误。如果在未声明变量时(如预期的那样)该行包含以下内容,它也可以工作:

if oError := rwfile.WriteLines(asParams, sParamsFilename); oError != nil {

如果我声明变量“oError”,则“:=”不起作用(如预期的那样)。

“rwfile”是我编写的一个包,所讨论的函数如下所示:

func WriteLines(asBuff []string, sFilename string) error { // write text file

如果我在写入文件时创建错误,并使用“=”而不声明变量“oError”,则程序正常工作并检测非零“oError”变量。

那么,当oError未被声明为变量时,为什么在上面使用“=”时不被视为错误?

Go版本是go1.1.2 Windows / 386。

2 个答案:

答案 0 :(得分:8)

这意味着您在包中的其他位置有一个名为oError的变量。 (请注意,此变量不能位于同一个文件中;它可能位于具有相同package子句的不同文件中。)因此,当您使用oError = ...时,您要为该包变量赋值,并且当您使用oError := ...时,您将声明一个隐藏包变量的局部变量。 (根据规范,“块中声明的标识符可以在内部块中重新声明。虽然内部声明的标识符在范围内,但它表示内部声明声明的实体。”[link])

如果您尝试使用另一个唯一的标识符,您应该会看到编译器确实会抱怨。

答案 1 :(得分:2)

这与实际问题无关,但是“go fmt”可以真正帮助跟踪大型程序中的错误内容。

另外,遵循风格指南确实有帮助:使用简洁的代码样式(没有匈牙利变量名称!花了我很多时间来习惯短名称)和短文件:2Kloc文件可能太大了。非常值得漫游标准库源代码,看看Go代码是什么样的