00:01
下面呢,我们来做几个关于变量作用域的练习题,我们一起来做一下这个题,大家看同学们注意啊,如果说同学们是在听视频的,你可以暂停一下视频,先自己想一想下面这段代码输出什么内容,然后呢再听老师的分析。OK。那现在呢?我们来一起分析一下这段代码输出什么内容。来,走一走,走一走吧,我们看。第一个。我们先来看这里输出什么,他说这里有一个main函数,这个main函数呢,它会输出一个name,大家看这个name它没有定义。这个在这没在函数内没有定义,我们就看外部有没有定义,诶我们发现这定了一个。变量,这个变量其实就是我们所说的什么呀,全局变量。但是这个变量呢,我们发现它的首字母是小写的。他手母小写,他首字母小写没问题,他首字母小写就意味着他在本包都是可以使用的,那么此时此刻这个命呢,也在本包,因此这句话是没问题的,它会输出什么呢?它会输出汤姆。
01:14
这个可以吧,这地方会输出汤姆没有问题吧。肯定是对的,然后呢,它又调用了test的零一,Test的零一是一个函数来看这里,它这里面又用到name。好,这个类目呢,它在本函数是没有定义的。也就是说在T01它没有定义,那这个时候呢,它就会使用什么,它就会直接使用外面的全局变量,因此这地方也输出汤姆。没有问题,紧接着它又调用了test的零二,注意看T的零二里边,大家看这里test的零二里面,它定义定义了一个name,问题来了。你。局部变量有个内。全局变量也有个name。那这会儿会报错吗?
02:01
先告诉大家不会报错,原因是因为你全局变量。我这有局部变量,那么在全局变量和局部变量有相同名的时候,它会采用一个就近原则。它会采用就是编译器,编译器采用。采用就近原则。就近原则。它会采用就近原则,那就说以你这个为准了。以你这个为准。对不对,那你以你这个为准的话,那这个地方会输出什么呢?各位这个地方就会输出Jackie。没问题吧,这会输出Jack,好,紧接着他又输出了T的零一,注意听这个T的零一。又重新回调这一个又再调一次,诶再调一次。注意听你这个Jack是在这定义过的,因此呢,它的改变并不会影响到全局变量的改变,因此它会再次输出一个汤姆。
03:00
最后的结果各位同学就是这样子的,第一个输出汤姆,这个地方会输出汤姆,这个地方会输出Jack,这个地方再次输出汤姆,因此结果是汤姆,汤姆,Jack汤姆,好,我们看看分析是否正确,我把这段代码复制一下,放到我们的Vs code里面进行一个测试,好,我放在哪里呢?我放在这个地方有个叫test go的代码里边去注意听讲。我把它放这就行了。好吧,我们做一个测试嘛。那这个地方呢?我把format这个包打开,我们保存一下,看有没有毛病。没没有报错,没有报错,我们就看运行一下,看看是不是像我们分析的汤姆汤姆杰克和汤姆走一个来吧,CD点点上一级,CD点点上一级。这里面有一个老师写的test go,就是刚才用的这个函数啊,用的这个文件,跑一个吧,Go wrong。
04:02
Test。点购我们看输出内容。我们可以看到输出的内容跟老师分析的是完全一致的,是汤姆汤姆,杰克汤姆,正确吧?正确,那么我再请同学们思考一下,如果说我把这个去掉了。先问大家一个问题,代码会报错吗?代码会不会报错,不会报错。因为这个。本身就没错嘛,对不对,但是我再问大家,此时此刻输出内容会会不会发生变化。那你如果说这地方没有冒号,就相当于说把这个阶梯重新付给这个全局变量了,也就是说这个时候这个name全局变量的name是一个了。那意思意思就是说这地方会输出JK,然后呢,当它调用完了之后,这个TEST0一再去输name的时候,这次也会输出JK,为什么?因为你在这个地方相当于修改了全局变量的内蒙。
05:01
因此这个地方也会输出。Jack说,这这样子运行的结果应该是汤姆,汤姆,Jackie和Jack搞懂了吗?大家看这块儿搞懂了吗?来吧,我们来运行一下,看看是不是跟老师分析的一样嘞,跑起来走。我们可以看到输入字是汤姆汤姆杰克,杰克理解。这是一个很很有意思的案例啊,大家好好去想一想,好的,我还把它撤回去吧,因为我就举一个案例,好,我还是写成汤姆。理解了啊。希望同学们能够把这个深刻理解好,我把这个案例呢给同学们放到笔记里面去,大家加深一个认识,就是关于变量的。课程练习。变量的。变量作用域的课堂练习。我把课堂练习呢给大家整,整理成标题三。好吧,标题三,然后我把案例给同学们放到这里面来输出结果,我也分析好了。
06:03
对不对。问题。给它放在这里,这是我们的第一个案例。第一个案例输出的结果,我们也把它整理一下,输出结果是。输出的结果是什么呢?就是刚才我们所说的汤姆,汤姆。Jack和汤姆。如果你把这个是第14行的冒号去掉,那输出结果是汤姆汤姆Jack Jack,我就不说了,这是一个案例,我们再看一个案例。再看一个案例,同学们看,这里有个案例,他说请思考下面的代码输出什么内容,他是怎么写的呢?V等于20这句话应该是OK的,没有,没有毛病。但是他这样写的一个东西,他说name冒号。等汤姆这句话行不行?这句话在这儿用行不行?再看一眼你你感觉好像,诶这个跟上面不是一样吗。
07:02
其实这是不一样的。其实这是不一样的,这个是在定义的时候就同时赋了值,但是这句话实际上它是等价于两句话,这句话其实是在编译期它会报错的,为什么呢?因为这句话它是等价于这样这样两句话,它是VR。VR name,它是这样子的,VAR name,然后是。这句话做完了,过后还有一句话是,Name等于汤姆。但是问题会出在这里。问题会出现,因为我们这个地方它是在。这这个定义它是在函数外定义的。在函数外你去定义一个变量没毛病,你去初始化一个变量也没毛病,但是你不能有复制语句,因为大家都知道这种语句它是一种,它是执行语句,这种执行语句它是要在一个函数体内才能执行的,因此你这句话等价于这句话的时候,等价于这两句话的时候啊,那么这句话。
08:07
这这个它是不能执行的,因为这隐藏了一个赋值语句,而赋值语句是不能够在函数外执行的,因此这个地方就会报错。比如说这个地方编译器直接给你擦掉。这是一个使用陷阱啊,同学们,这是一个使用陷阱,一定要高度重视,那是不是这样子的呢?同学们,老师给大家演示一下。非常简单,我打开Vs code,我就在这直接写个东西,你们一看就会报错。啊,比如说我写一个大写的name。然后我直接用类型推导。大家看,比如说我给他了一个J,呃,Mary。大家看这种会报错这个地方,这个地方会报错。汇报的错误大家看我保存一下,马上提示错误。就看效果。大家看这方是不是报错了,他说有个语法错误,他说你没有声明一个这个,他说no none DEC statement outside outside of function outside of function body,什么意思呢?就是说你这里面有一个不能够放在函数体外的一个语句。
09:23
哪个语句,就是因为你这边其其实隐藏了两条语句,一个是丁声明,一个是复制,而这个复制语句是不允许在外面执行的,所以说这个写法是错的。理解吗?这写法是错的啊,好。那我把这个错误代码也给大家说到这里。这个地方是错的。我总结一下,这个地方是错的。直接擦掉。原因是这儿。我把这个原因给大家写到这里来。原因。错误的原因。错误的原因。
10:00
啊,因为。因为。因为什么呢?因为这个name。他的类型推导这个汤姆,他其实等价于两句话。好等价,等价什么呢?VR name是寸,然后你还有一个name等于这个。com这个地方是不允许的。对对不对,所以这可能会错,因为语句就是赋值语句,赋值语句,语句不能。不能在。不能在函数体外。所以报错,所以错。所以就错了。好了,原因我也说清楚了,别人问到你,你把这个给他抛出来就可以,一定不要这么去用啊。你如果错了的话,你别说,诶老师没有讲过,那就那就不对了,老师是讲过的。好,我把这个样整理到这里。
11:00
好,那关于我们变量作用域的两个课堂练习呢,就给大家讲到这里,希望大家能够通过这两个练习,加深对变量作用域的一个理解。
我来说两句