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")

       达到预期目的。

归纳总结:

  • 尽量少的使用全局变量。
  • 尽量少的使用:=语法糖。
  • 使用:=的时候要确保左值没有被定义过。

       要对全局变量,局部变量有明确清晰的认知,使用起来就能够游刃有余,得心应手。

猜你喜欢

转载自blog.csdn.net/Roker_966/article/details/105052339