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混淆,就很容易产生意想不到的错误。

posted on 2023-11-28 16:09  shui00cc  阅读(38)  评论(0编辑  收藏  举报