Go-知識簡短變量聲明
- 1. 簡短變量聲明符
- 2. 簡短變量賦值可能會重新聲明
- 3. 簡短變量賦值不能用于函數外部
- 4. 簡短變量賦值作用域問題
- 5. 總結
githuio地址:https://a18792721831.github.io/
1. 簡短變量聲明符
在Go語言中,可以使用關鍵字var
或直接使用簡短變量聲明符:=
聲明變量。
相比而言,使用:=
更多一些,而且使用:=
可以自動推斷類型,而不需要關注類型問題。
比如:
a := "string"a := 2a := struct{}
2. 簡短變量賦值可能會重新聲明
使用:=
可能會重新聲明變量,導致出現在不同的作用域中,很可能創建了新的同名變量,導致同一個函數不同作用域的同名變量不符合預期。
多說無益,請看如下代碼:
func TestTmpVar(t *testing.T) {a := 1a++fmt.Printf("a=%d\n", a)if a > 0 {a, err := addNum(a)if err != nil {fmt.Printf("err=%s", err)}fmt.Printf("a=%d\n", a)}fmt.Printf("a=%d\n", a)
}
func addNum(a int) (int, error) {return a + 1, nil
}
請想想上述代碼輸出結果是什么?
上面的寫法非常常見,使用:=
調用了一個函數,然后接收函數返回的結果,如果有錯誤,那么處理錯誤,沒有錯誤,那么將結果賦值給變量。
但是要非常注意,因為a
已經在外部聲明了,而方法調用又是在if
內部,所以就相當于在if
內,創建了一個同名函數,并沒有按照我們的預期處理。
如果a
是指針,那么,后面在使用a
的時候,肯定會出現空指針panic
。
為什么會出現這樣的問題呢?
這是因為:=
的規則:
當
:=
左側存在新變量時(err
),已聲明的變量(a
)會被重新聲明,不會有其他額外的副作用。
當:=
左側沒有新變量是不允許的,編譯會提示no new variable on left side of :=
所以如果當一個變量第一次聲明和后續全部使用過程中,都在同一個作用域內時,上述使用確不會出現問題,因為作用域相同。
比如上述代碼如果去掉if
:
func TestTmpVar(t *testing.T) {a := 1a++fmt.Printf("a=%d\n", a)//if a > 0 {a, err := addNum(a)if err != nil {fmt.Printf("err=%s", err)}fmt.Printf("a=%d\n", a)//}fmt.Printf("a=%d\n", a)
}
func addNum(a int) (int, error) {return a + 1, nil
}
輸出如下
因為雖然使用:=
重新定義了新的變量,但是在后面使用的過程中,使用的也是新的變量。
3. 簡短變量賦值不能用于函數外部
簡短變量賦值只能用于函數內,不能使用:=
來聲明和初始化全局變量。
比如:
package study
test := "test"
會出現編譯錯誤,提示為syntax error: non-declaration statement outside function body
。
可以理解為:=
實際上會拆分成兩個語句,一個是聲明,一個是賦值。而賦值語句不允許出現在函數外部。
4. 簡短變量賦值作用域問題
考慮最開始的例子,假設變量時指針類型。
type tes struct {a intz string
}func TestTmpStruct(t *testing.T) {a := tes{a: 1,z: "1",}a.a++fmt.Printf("a = %+v, %#p\n", a, &a)if a.a > 0 {a, err := addNumStruct(a)if err != nil {fmt.Println(err)}fmt.Printf("a = %+v, %#p\n", a, &a)}fmt.Printf("a = %+v, %#p\n", a, &a)
}
func addNumStruct(a tes) (tes, error) {a.a++return a, nil
}
查看輸出,可以很明顯的看到創建了新的變量:
那么新的問題來了,假設不是if
,而是for
那么:
可以很明顯的看到創建了很多的變量,這些變量屬于for
作用域內的臨時變量,當大量生成臨時變量時,
雖然Go不需要我們管理內存,但是會導致程序性能的下降。
5. 總結
簡短變量聲明操作符:=
雖然很好用,但是需要注意:=
的特性,在使用的時候,需要避免因為使用:=
而導致的同名變量聲明,以及作用域內無效變量的聲明。