全局错误变量在初始化后仍保持为nil。

huangapple go评论64阅读模式
英文:

global error variable remains nil after initialization

问题

当我在全局初始化一个错误变量时,似乎在同一个包中的另一个函数中它是nil的。
我不明白为什么这段代码没有引发错误?

package main

import (
	"os"
	"fmt"
)

var loadErr error

func main() {
	f, loadErr := os.Open("asdasd")
	if loadErr != nil {
		checkErr()
	}
    if f != nil {
        fmt.Println(f.Name())
    }
}

// 由于loadErr是nil,所以不会引发panic
func checkErr() {
	if loadErr != nil {
		panic(loadErr)
	}
}

但是当我这样做时,它似乎按预期工作?

package main

import (
	"os"
)

var loadErr error

func main() {
	_, err := os.Open("asdasd")
	loadErr = err
	if loadErr != nil {
		checkErr()
	}
}

// 如预期,将引发panic
func checkErr() {
	if loadErr != nil {
		panic(loadErr)
	}
}
英文:

When I initialize an error variable globally it seems that it's nil to another function in the same package.
I don't understand why is this code not panicing?

package main

import (
	"os"
    "fmt"
)

var loadErr error

func main() {
	f, loadErr := os.Open("asdasd")
	if loadErr != nil {
		checkErr()
	}
    if f != nil {
        fmt.Println(f.Name())
    }
}

// panic won't be called because loadErr is nil
func checkErr() {
	if loadErr != nil {
		panic(loadErr)
	}
}

But when I do this, it seems to work as expected?

package main

import (
	"os"
)

var loadErr error

func main() {
	_, err := os.Open("asdasd")
	loadErr = err
	if loadErr != nil {
		checkErr()
	}
}

// panic will be called as expected
func checkErr() {
	if loadErr != nil {
		panic(loadErr)
	}
}

答案1

得分: 10

func main() {
_, loadErr := os.Open("asdasd")

你创建了一个__新的、局部的__变量loadErr,全局的变量没有被设置。使用=而不是:=来使用全局的变量。

编辑:为了同时保存第二个值,你需要预先声明第二个变量:

var f *os.File
f, loadErr = os.Open("asdasd")

不幸的是,在这里你不能使用:=,因为:=不会考虑非局部变量,在这种情况下只会创建一个局部变量。

英文:
func main() {
    _, loadErr := os.Open("asdasd")

You create a new, local variable loadErr, the global one is never set. Use just =, not :=, to use the global one.

Edit: To hold the second value too, you have to predeclare the second variable:

var f *os.File
f, loadErr = os.Open("asdasd")

Unfortunately, you can't use := here, as := will not consider non-local variables and just create a local variable in this case.

答案2

得分: 6

短变量声明会在左侧的变量在外部作用域中已经声明的情况下创建新的变量。即使左侧的变量并非全部都是新的,这一点也是正确的,否则会出现_重新声明_的情况(它不会引入新的变量,只是给原始变量赋予新值)。

因此,如果你想给全局变量赋值,不要使用短变量声明,而是使用简单的赋值。当然,对于一个元组赋值,其中一个变量已经在之前声明过,你必须先声明另一个变量:

var f *os.File
f, loadErr = os.Open("asdasd")
if loadErr != nil {
    // 处理错误
}

你可以更简洁地编写它:

var f *os.File
if f, loadErr = os.Open("asdasd"); loadErr != nil {
    // 处理错误
}

还有另一种使用短变量声明的选项,但是你必须“手动”将错误值分配给全局的loadErr变量:

f, err := os.Open("asdasd")
loadErr = err
if err != nil {
    // 处理错误
}

或者更简洁一些:

f, err := os.Open("asdasd")
if loadErr = err; err != nil {
    // 处理错误
}

参见相关/可能重复的问题:https://stackoverflow.com/questions/34195360/golang-how-to-use-global-var-across-files-in-a-package/34195389#34195389

英文:

The short variable declaration creates new variables if the variables on the left side have been declared in an outer scope. This is also true if not all variables are new on the left side, which otherwise would be redeclaration (which does not introduce a new variable; it just assigns a new value to the original).

So if you want to assign value to the global variable, don't use short variable declaration but simple assignment. Of course, for a tuple assignment where one variable has been declared earlier, you must declare the other one too prior:

var f *os.File
f, loadErr = os.Open("asdasd")
if loadErr != nil {
    // Handle error
}

You can write it more compact:

var f *os.File
if f, loadErr = os.Open("asdasd"); loadErr != nil {
    // Handle error
}

There is also another option using short variable declaration, but then you must "manually" assign the error value to the global loadErr variable:

f, err := os.Open("asdasd")
loadErr = err
if err != nil {
    // Handle error
}

Or more compact:

f, err := os.Open("asdasd")
if loadErr = err; err != nil {
    // Handle error
}

See related / possible duplicate question: https://stackoverflow.com/questions/34195360/golang-how-to-use-global-var-across-files-in-a-package/34195389#34195389

huangapple
  • 本文由 发表于 2017年3月14日 15:57:45
  • 转载请务必保留本文链接:https://go.coder-hub.com/42780555.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定