初始化后,全局错误变量保持为零

时间:2017-03-14 07:57:45

标签: go

当我在全局范围内初始化一个错误变量时,似乎它对于同一个包中的另一个函数是零的。
我不明白为什么这段代码不会慌乱?

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)
    }
}

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

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)
    }
}

2 个答案:

答案 0 :(得分:5)

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

您创建新的本地变量loadErr,永远不会设置全局变量=。仅使用:=而不是var f *os.File f, loadErr = os.Open("asdasd") 来使用全局版本。

编辑:要保留第二个值,您必须预先声明第二个变量:

:=

不幸的是,你不能在这里使用:=,因为c:\psexec\psexec \\%%M -d -c "%~dp0LS-PrePost-3.0-Win32_setup.exe" /quiet /silent /norestart 不会考虑非局部变量,只是在这种情况下创建局部变量。

答案 1 :(得分:3)

如果左侧的变量已在外部short variable declaration中声明,则scope会创建新变量。 如果并非左侧的所有变量都是新的,则也是如此,否则将是重新声明(它不会引入新变量;它只会为新变量赋值原文)。

因此,如果要为全局变量赋值,请不要使用简短变量声明,而应使用简单assignment。当然,对于之前声明了一个变量的元组赋值,您必须先声明另一个变量:

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

你可以写得更紧凑:

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

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

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

或更紧凑:

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

查看相关/可能重复的问题:How to use global var across files in a package?