英文:
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
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论