Go语法糖——简短变量声明“:=”
参考地鼠文档——GO专家编程中的内容,我总结了关于 := 的几条规则,并以代码举例的运行结果来说明可行性,以避免编程中出现一些陷阱。
-
规则一:不能用于函数外部
package main import "fmt" rule := "Short variable declarations" func main() { fmt.Println(rule) }
编译错误提示syntax error: non-declaration statement outside function body
,表示非声明语句不能出现在函数外部。可以理解成:=
实际上会拆分成两个语句,即声明和赋值。赋值语句不能出现在函数外部的。
-
规则二:左边必须有新变量,多变量赋值时旧变量可能会重新赋值
func fun() { i := 0 i, j := 1, 2 fmt.Printf("i = %d, j = %d\n", i, j) }
多变量声明时,按照以下规则:
- 当
:=
左侧存在新变量时(如 j ),那么已声明的变量(如 i )则会被重新声明,不会有其他额外副作用。 - 当
:=
左侧没有新变量是不允许的,编译会提示no new variable on left side of :=
。
>>> i = 1, j = 2
-
规则三:变量作用域问题
func fun() { i, j := 0, 0 if true { j, k := 1, 1 fmt.Printf("j = %d, k = %d\n", j, k) } fmt.Printf("i = %d, j = %d\n", i, j) }
注意 block if 中声明的 j ,与上面的 j 属于不同的作用域,因此两者是两个作用域中同名的不同变量。代码结果如下:
j = 1, k = 1 i = 0, j = 0
当 := 使用过于频繁时,我们需要注意作用域的陷阱,看如下代码:
func Redeclare() { field, err:= nextField() // 1号err if field == 1{ field, err:= nextField() // 2号err newField, err := nextField() // 3号err ... } ... }
注意上面声明的三个err变量。
2号err与1号err不属于同一个作用域,:=
声明了新的变量,所以2号err与1号err属于两个变量。
2号err与3号err属于同一个作用域,:=
重新声明了err但没创建新的变量,所以2号err与3号err是同一个变量。
如果误把2号err与1号err混淆,就很容易产生意想不到的错误。