GO中全局變量和局部變量的區別及其使用:=賦值需要注意的事情

概念定義:

全局變量:

  • 定義:在函數外部的變量稱爲全局變量
  • 作用域:同一個包內的任何地方

局部變量:

  • 定義:定義在{}裏面的變量爲局部變量
  • 作用域:只能在{}裏面有效;執行到定義的那句話,開始分配內存空間,離開作用域自動進行釋放

   

問題描述:   

       在我們學習go語言時,通常會使用golang的一個語法糖:=來給變量賦值,這種方式可以節省掉我們定義變量的代碼,讓代碼變的更加簡潔。

       但是如果你定義了一個全局變量,又不小心用:=來給它賦值,就會出現一些問題。如下:

package dbops

import (
	"database/sql"
	_ "github.com/go-sql-driver/mysql"
	"log"
)
var (
	dbConn *sql.DB
	err error
)
func init() {
	dbConn, err := sql.Open("mysql","root:000000@tcp(localhost:3306)/server?charset=utf8")
	if err != nil{
		panic(err.Error())
	}
	log.Println(dbConn)
}

func main()  {
	log.Println("查看全局變量dbConn:",dbConn)
}

在這裏我們用的是  := 給全局變量賦的值,結果是全局變量並未賦值成功。執行會報錯。

panic: runtime error: invalid memory address or nil pointer dereference [recovered]
	panic: runtime error: invalid memory address or nil pointer dereference
[signal 0xc0000005 code=0x0 addr=0x0 pc=0x5b0a61]

原因分析:

       執行之後,發現在init中明明給dbConn賦值,單在main中卻是nil。弄清楚局部變量和全局變量,不難發現,init中的dbConn是用:=生成的,所以這裏的dbConn是局部變量,只不過是在init函數中覆蓋了全局變量dbConn。全局變量dbConn並沒有被賦值,它還是原來的nil。

解決方法:

       將 := 用 = 替換

dbConn, err = sql.Open("mysql","root:000000@tcp(localhost:3306)/server?charset=utf8")

       達到預期目的。

歸納總結:

  • 儘量少的使用全局變量。
  • 儘量少的使用:=語法糖。
  • 使用:=的時候要確保左值沒有被定義過。

       要對全局變量,局部變量有明確清晰的認知,使用起來就能夠遊刃有餘,得心應手。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章