函数作用域
一、局部变量
前面我们定义的函数中,都经常使用变量。那么我们看一下如下程序的输出结果:
func Test() {
a := 5
a += 1
}
func main() {
a := 9
Test()
fmt.Println(a)
}
最终的输出结果是9,为什么呢?在执行fmt.Println(a)
语句之前,我们已经调用了函数Test()
,并在该函数中我们已经重新给变量a
赋值了。但是为什么结果没有发生变化呢?这就是变量的作用范围(作用域)的问题。在Test()
函数中定义的变量a
,它的作用范围只在改函数中有效,当Test()
函数执行完成后,在该函数中定义的变量也就无效了。也就是说,当Test()
函数执行完以后,定义在改函数中所有的变量,所占有的内存空间都会被回收。
所以,我们把定义在函数内部的变量称为局部变量。
局部变量的作用,为了临时保存数据需要在函数中定义变量来进行存储,这就是它的作用。
并且,通过上面的案例我们发现:不同的函数,可以定义相同的名字的局部变量,但是各用个的不会产生影响。例如:我们在main()
函数中定义变量a
,在Test()
函数中也定义了变量a
,但是两者之间互不影响,就是因为它们属于不同的函数,作用范围不一样,在内存中是两个存储区域。
二、全局变量
有局部变量,那么就有全局变量。所谓的全局变量:既能在一个函数中使用,也能在其他的函数中使用,这样的变量就是全局变量.也就是定义在函数外部的变量就是全局变量。全局变量在任何的地方都可以使用。案例如下:
var a int //变量定义在函数外面
func Test() {
a := 5
a += 1
}
func main() {
a := 9
Test()
fmt.Println(a)
}
注意:在上面的案例中,我们在函数外面定义了变量a
,那么该变量就是全局变量,并且Test()
函数和main()
函数都可以使用该变量。该程序的执行流程是:先执行main()
函数,给变量a
赋值为9,紧接着调用Test()
函数,在改函数中完成对变量a
的修改。
由于main()
函数与Test()
函数所使用的变量a
是同一个,所以当`Test( )函数执行完成后,变量的a已经变成了6.回到main( )函数执行后面的代码,也就是 fmt.Println(a),输出的值就是6.
可能有同学已经发现该程序和我们前面写的程序还有一点不同的地方是:第一个程序我们是a:=9,但是第二个程序执行修改成了a=9,现在修改一下第二个程序如下:
var a int //变量定义在函数外面
func Test() {
a := 5
a += 1
}
func main() {
a := 9 // ====》注意这里
Test()
fmt.Println(a)
}
该程序与上面的程序不同之处在于,该程序是a:=9
,上面的程序是a=9
。
现在大家思考一下该程序的结果是多少?最终结果是9。原因是a:=9
等价于:
var a int
a=9
也就是定义一个整型变量a
,并且赋值为9
。
那么现在的问题是,我们定义了一个全局变量a,同时在main()
中又定义了一个变量也叫a
,但是该变量是一个局部变量。
当全局变量与局部变量名称一致时,局部变量的优先级要高于全局变量。所以在main()
函数中执行fmt.Println(a)
时输出的是局部变量a
的值。但是Test()
函数中的变量a
还是全局变量。
注意:大家以后在开发中,尽量不要让全局变量的名字与局部变量的名字一样。
所以大家,思考以下程序执行的结果:
var a int //变量定义在函数外面
func Test() {
a := 5
a += 1
fmt.Println("Test",a)
}
func main() {
a := 9
Test()
fmt.Println("main",a)
}
三、总结
- 在函数外边定义的变量叫做全局变量。
- 全局变量能够在所有的函数中进行访问。
- 如果全局变量的名字和局部变量的名字相同,那么使用的是局部变量的,小技巧强龙不压地头蛇。