[转] go --- err is shadowed during return

 

1 前言

有时候编译Go项目会出现GO err is shadowed during return的问题,是因为作用域导致变量重名,return时不是你预期的变量导致的。

2 样例

这里先复现问题,然后进行问题说明。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
//test.go
package main
 
 
import "fmt"
import "strconv"
 
 
func foo(x string) (ret int, err error) {
    if true {
        ret, err := strconv.Atoi(x)
        if err != nil {
            return
        }
    }
    return ret, nil
}
 
 
func main() {
    fmt.Println(foo("123"))
} 

运行:

 

OK,问题复现了,下面进行问题分析。

1
2
3
4
5
6
7
8
9
func foo(x string) (ret int, err error) {//返回值列表定义了ret和err变量,作用域是整个函数体
    if true {//新的语句块
        ret, err := strconv.Atoi(x)  //这里又定义了新的变量ret和err,和返回值列表重名了。作用域是if语句块
        if err != nil {
            return  //这里的return语句会导致外层的ret和err被返回,而不是if语句里的ret和err
        }
    }
    return ret, nil
}

来自网上的解释:

It's a new scope, so a naked return returns the outer err, not your inner err that was != nil.
So it's almost certainly not what you meant, hence the error.

下面进行修改(只需要保证局部变量和全局变量不重名即可):

3 解决方案

1
2
3
4
5
6
7
8
9
10
11
12
func foo(x string) (ret int, err error) {
    if true {
        ret1, err1 := strconv.Atoi(x)
        if err1 != nil {
            err = err1
            return
        }
        ret = ret1
    }
 
    return ret, nil
}

运行:

另一种解决方法:

声明新的变量, 避免重新实例化err.

原文地址:https://www.cnblogs.com/mafeng/p/11301464.html