常见的情形就是:在if条件语句块或for循环语句块中,使用“:=”给一个与外部同名的变量赋值
直接看个例子:
package main
import "fmt"
func returnSomething() (int, bool) {
return 0, true
}
func main() {
var errOrNot = false
a := 1
if a > 0 {
// var res int
res, errOrNot := returnSomething()
fmt.Printf("res: %v errOrNot: %v\n", res, errOrNot)
}
fmt.Printf("errOrNot: %v\n", errOrNot)
}
输出:
res: 0 errOrNot: true
errOrNot: false
显然,if条件语句块中获得的新errOrNot值没有按照预期被带出来,这是因为条件语句块内部的这个errOrNot是一个覆盖了外围errOrNot的全新短变量。
如果这样写:
package main
import "fmt"
func returnSomething() (int, bool) {
return 0, true
}
func main() {
var errOrNot = false
a := 1
if a > 0 {
var res int
res, errOrNot = returnSomething()
fmt.Printf("res: %v errOrNot: %v\n", res, errOrNot)
}
fmt.Printf("errOrNot: %v\n", errOrNot)
}
输出:
res: 0 errOrNot: true
errOrNot: true
可见,整个代码中就只有一个errOrNot变量。
这种错误在函数返回一个具名变量时也容易出现,因为具名变量也相当于声明了一个变量,此时这种错误往往也伴生在if语句或者for语句的条件块中:
func shadow() (err error) {
x, err := Check1()
if err != nil {
return //能正常返回错误
}
if y, err := Check2(); err != nil {
return //返回nil
}
fmt.Printf("x:%v y:%v\n", x, y)
reutrn
}
所以,if语句或者for语句中使用短变量声明时一定注意。