00:00
大家好,我们接着来为大家讲解go语言里面的函数。那前面呢,我们已经把函数的相互调用,就是我怎么把一个函数放在一个文件里面去,然后呢,利用包的机制进行这个相互调用,对吧,我们已经说过了,那现在呢,我们要对函数做一些比较深入的探讨和了解。那现在呢,我们应该给大家讲的是函数的调用机制,这一块同学们特别的重要啊,就说在我们学构语言或者是其他编语言里边呢,函数的调用机制可以说是非常重要一个知识点,如果同学们没有把这个调用机制搞清楚,那么后边咱们遇到递归或者用到一些数据结构的东西的时候呢,大家会比较茫然。那现在呢?我们来给大家看一下函数调用机制到底是怎么回事。首先呢,我们先找一个比较通俗易懂的方式,帮助大家理解函数的调用机制,非常的简单,说这里有拉登,拉登呢,给特工小组下达一个命令,说炸掉白宫,OK,那么这个特工小组他能不能把这个白宫炸掉呢?最终他会返回一个结果跟给这个拉弓,那给这个拉拉登同志对不对,很简单,其实你看这里面就有一个下达命令执行。
01:23
就是我们的这个特工小组去执行,然后呢,特工小组执行完了过后,会把这个结果返回给拉登。这是一个通俗的,就是在现实生活中的一种情况,那么在程序里边我们怎么去理解呢?好,拉登就变成程序员呢?程序员去调用方法,这个方法就是我们要去完成一段完成一个功能的一段代码的集合,然后呢,方法执行完毕过后,会返回一个结果给这个程序员,或者说返回给调用者。这其实就有了类似好这个呢,是一个比较通俗易懂的理解,对不对,但是呢,它不够深入,也不够本质,那现在呢,我们换另外一种方式,就是深入到我们的代码里边去分析,从代码执行的这个角度来分析一下函数的调用机制,OK,好的,我们现在呢,先把刚才的笔记给同学们补一下。
02:23
刚才的笔记给同学们补一下。好的,嗯,我们还把笔记打开,对不对,我们还把笔记打开。那上次呢,笔记我们已经讲到哪里了,来看一下。笔记我们已经讲到哪里了,我们看一下啊。稍等片刻,打开的时候会稍微慢一点。好,这块我们可以显示级别,显示到第二个级别就可以了,那现在呢,我们定一下位。好,我们已经讲到包的使用对不对?好,现在呢,我们来看一下函数的调用机制,也就是说我们前面讲了一下函数的基本使用,现在呢,我们要回头在这个有这个包的基础上呢,再回头看包,那再回头看函数有哪些需要同学们注意的地方。
03:15
来,同学们看一下。现在我们要说的这个东西呢,就是叫做函数的调用机制。这个呢,我给他一个标题二。没问题吧,给他一个标题二。啊,刚才我讲了一个通俗易懂的理解方,诶,这个怎么回事啊。很讨厌对不对,很讨厌这般就是什么呢?就是第一种就是通俗。通俗易懂的方式的一个理解,那这块呢,讲的相对来说就是它是一个表面的东西,那本质的东西呢,待会儿我们就再来分析。好,我把这个呢就拿过来了,好吧,同学们,我把这一块呢,就拿到我们的笔记里面去。
04:01
接着呢,我们再来看函数的调用机制,举例说明,同学们看这里。函数的调用过程,为了让大家更好的理解函数调用的过程呢,怎么样?我呢,给大家看两个案例。并且呢,我要画出里面底层的这个示意图,这个很重要,我举两个例子,第一个案例呢,就是传入一个数,对这个数加一。第二个案例呢,是计算两个数,并返回这个结果。大家理解我的意思了吧,好,我们现在完成第一个。把这个呢,稍微的给大家整理一下,这是我们的函数的调用过程,我板述一下。好,这是我们的第二一个啊,第三个标题。这是我们的第三个标题,那这里呢是一个介绍。对吧,然后呢,这有一个案例。这是第一个案例,就是传入一个数呢,然后我们再怎么样再对它进行一个加一的操作。
05:02
这是第一个案例。我把这板输一把。好的,那传入一个数,对它加一其实是一个很简单的一个操作,那关键说我们在函数这个层面上怎么去做呢?打开我们的这个。呃,V code,然后呢,我新建一个文件夹,OK,新建一个文件夹,取个名字叫fun。DEMO。零二。然后呢,在这里边。我新建一个文件,大家注意看,新建一个文件叫main顶购。OK,还是老规矩,前面呢,有一段代码是它的一个架构。架构主体的这一部分呢,我粘过来好吧,这块我先不要了。然后呢,在这里面我就来做这个事情。怎么做呢?非常简单,我们编写一个函数。
06:02
编写,甘肃。这个函数的名字我们就命名为test,对吧,很简单,Fun。Test,我接收一个数N1。数据类型为int类型。包起来。那么我拿到这个数以后,我要对它加一,我怎么加呢?非常简单,就是比如说我这样做,N等于N1加一完活了。然后呢,我输出我输出这个。运算过后的值N等于多少呢?就等于N1完事。这个函数非常的简单,那我们在主函数里边怎么去调用它呢?调用。哎,我们来调用我们的test没问题吧。那怎么去调用?非常简单,一个标准的调用方式是先定义一个变量,我们也叫N1,我故意给他取个名字叫N1的啊。
07:01
为什么?我就是让大家看到两个都有NE1的时候,在底层的代码里边,他在内存里面究竟是用一种什么样的机制来进行运算和操作的,那我就命名为N1,然后呢,我给他一个值。好,这里我用的是这个类型推导的方式来定义了一个变量叫N,然后呢,我调用它非常简单,诶对了,这个地方我们不叫调用,这个叫定义,我把它放到这里来没问题吧,然后呢,调用它test。我把这个N一传进去,看到大家看啊,这有N1,这有N1,这有N1,这儿还有两个N1,大家是不是瞬间蒙圈了。没关系,待会儿呢,老师一画图,你们马上就明白了,我故意把它都命名为N1啊,好,同学们,我们现在呢运行一把。刚才老师写的这段代码,我们来看看输出的结果是什么,大家想一想输出什么结果?
08:02
哪里?说出什么结果呢?大家可以动动脑筋想一想,其实非常简单哈。我现在可以把答案告诉大家,就是11。但是我要在这里再次输出一个值,引起同学们的思考。Print LN,我在这里呢,也输出一个N1。等于N,同学们请思考这里又输出一个什么内内容这地方我要先挂个问号。OK,这么。这个地方其实我应该先给他留,卖个关子,我画个问号。啊,打一个问号,问号在这里,那为了区别这个N1和N这两个都这样输出的话呢,会有一个什么问题呢?同学们,就是我也不知道是test。函数里边输出等于一还是main函数里边输出的一怎么办?说一个test。对不对,在这里面咱们写一个命对不对,好了,这你也可以区分了,那现在同学们呢,我们先不去运行这个结果,我们先从内存的角度来分析,分析完了过后我们再去执行。如果。
09:13
执行的结果和我们分析结果相同,那则说明我们分析到位了。如果我们分析的和输出结果不不一样,这说明我们的分析是有问题的,对不对?来,现在呢,老师先打开我们笔记里面的go浪讲解的示意图。我们来分析吧。打开这个示意图,我们来走一走。那么在这里呢,我们就来说明一下,在构中。在构中,勾纳中函数。函数。诶,函数调用的一个机制的底层分析。那丽岩,然后让我在这里呢?
10:00
为了好看,我把这个字体稍微的调大一点点。来吧,各位同学,首先。我们要说一个大的概况,就是在程序运行的时候呢,在内存里边会把我们这一个进程执行的过程,把它在执行的过程中,我们这个进程会把内存分成了三个部分,当然我说的内存是操作系统给它分配的这一部分的内存啊,这一块呢,我们管它叫战区。没问题。这块。我们管它叫堆曲。没问题吧,叫堆区。还有一块呢,从大的层面来说,还有一块就是要我们叫做代码区。OK。那么不同的这个程序语言呢,它还有一些微小的差别,我们先这样子简单的划分一下。河北战区,河北堆区,河北代码区,听其名而知其意。战区一般来讲就是我们的函数在调用的过程中,在执行的过程中,我们的基本数据变量是分配在战区的,也就是你可以理解存基本数据类型。
11:16
基本数据类型。类型一般来说,一般说一般来说是在这里分配的,是分配到哪里的呢?是战区的。占区。为什么我这里说是一般说,因为在构元里面呢,它的编译器有一个叫逃逸分析的一个特点。所以说,不一定所有的基本数据类型都分配在战区。注意,听我说的这句话。而且老师画的这个区呢,其实不是物理上的划分。而是逻辑上的划分。明白,所以说我们可以理解成基本数据的,一般来说分析到分配到这个战区,因为呢,在这个go里面,它的编译器,编译器存在一个逃逸分析。
12:11
逃逸分析,这个是我们的,就是go语言的设计者K汤mpson。他呢,在这里面做对这个编译器做了一个优化啊,后面加了逃逸分析,那也就是说基本数据类型呢,不一定完全分分配在战区的,但是一般来讲是分配在战区的。OK,那么堆区呢,各位同学,那老师就省点事了啊,我把这句话呢,就粘贴复制到这里来,一般来说呢,我们的引用数据类型。引用。引用数据类型。一般来说,分配在堆区的。理解什么东西呢?堆区和什么应用类型呢,你比如说map。对不对,你比如说我们的这个切片啊,后面呢,大家用到的这些东西,它一般分配在堆区的。
13:03
你比如说你学的Java Java语言里面的对象呢,诶一般来说分配在对区里面的理解,那么代码区听其名而知其意,就是我们本身这个代码在执行的过程中,它本身你的这个指令,你的计算机指令。它要存取啊,那我们的CPU怎么知道要进行加减乘除呢?就是因为你有代码,比方说刚才老师写的这样一些代码,它总得有个地方存呐。他得存这些代码,它不存代码,那计算机他怎么知道要执行什么东西呢?对不对,就就好比好比我们人要去拍一个电影,你首先得有剧本吧,你没有剧本你怎么拍电影呢?所以说我们的代码呢,一般来说代码本身。代码啊代码。代码会什么到这里。OK。好的。
14:00
OK,那既然有了这样几个划分了过后呢,诶,我们再来讲这个东西呢,就相对来说就比较轻松了,对吧,刚才老师已经把这个代码写好了,来吧,现在为了让大家听得明白。听的比较到位呢,我把这一段代码。整个放到我们的Excel表里面去。注意了,现在你应该想象到,你就是一个计算机,你就是CPU。那么我这里用一个箭头来表示我们代码执行到哪句话了?我用了一个绿色的线来表示目前我们的代码已经执行到哪一行了,然后结合我们的内存来进行分析,同时呢,我在这个地方再画出我们的一个终端输出。这个地方我们理解成这个终端输出位置啊,终端。终端输出界面,也就是说同学们现在看到了哪个玩意儿呢?就是待会运行起来的时候,你们看到这个东西。
15:03
来吧,我把这个也打开。给同学们一。跟上老师的思路,进入到刚才我们写的代码chapter里面的function demo02,输入一个CD。进去理解,然后呢,待会儿我们这个控制台里面输出东西呢,你就认为是老师画的这个地方来了,我们现在一步一步的分析。首先当我代码执行到N1。这个给他来了一个,来了一个类型推导的一个值啊,就是N1,我们估计就叫N1,定义了一个N1等于十,那这个时候在我们内存里边,注意这块是内存再说一遍。这块。是我们可爱的内存。这一块是我们代码执行的部分,这一块是我们看到输出能理解三大块儿啊。好,那现在老师开分析,首先进入到这个N1的时候呢,你可以认为注意听,你可以认为在这个战区里边呢,它会划分一个空间。
16:07
最近我这句话啊,为了大家看的清楚一点呢,我会用一个颜色,你可以认为它在战区里面划分了一块空间。那这个空间呢,也是一个逻辑上的空间啊,就整个这一大块,再说一遍,整个这一大块是一个战区。理解整个这一大块是一个战区,战区那么你每一个函数呢,每一个函数在调用的时候呢,它也会有一个数据的这个导入,或者说在这边也会给它分配一个空间,从这个大的战区里面给它分配一个空间,我们姑且要把它叫做may好不好,为了因为待会呢,我为了区分这一块的main里面的数据的空间和test的空间不一样呢,我给它取个名字叫main,你可以简单认为就是占区。但实际上啊,老师画的这个图呢,是逻辑上的东西,并没有说在内存里面真的真的存在这么一个玩意儿,就说我该取个名叫命战区,是为了让大家比较容易理解,那么你可以理解成在main函数里面的基本数据类型呢,都会在这里面分配空间,能理解。
17:15
好,此时此刻N1里边呢,我们就认为有个N1这个变量。他分配了一个空间,它等于多少呢?好,我用这个框框来表示啊,他给了一个值等于十,OK,也就是说第一句话执行完毕过后就N1,等于使这句话执行完毕过后,你可以认为在这个大的战区里边有一个空间。里面有一个N1的变量,它。的对应的值是十。理解。此时此刻,我们又调用了第二把test。Test的这个N1,这个test的N1呢,这个就是函数调用函数,注意听这里这个很重要了,根据我们操作系统的原理和它的机制规定。
18:01
当一个当一个成,当一段这个代码去调用一个函数的时候呢,它会再开辟一个空间,或者给他分配一个空间,这个空间还是逻辑的空间啊,那么你可以认为在这地方又有一个空间了。叫什么呢?叫test的战区,注意听我讲,同学们在真实的这个再说,我再说一遍啊,在真实的这个内存里面是没有这个test的战区和main战区这个区分的,但是我为了讲个方便呢,我给它取了个名字,那在底层的编译器里面,它怎么区分main战区和test的战区呢?其实它会有一种,它底层会有一种方式来区分这两个战区的一个分界线。但是这块因为涉及到编译原理和编译器的东西呢,老师这里就不展开讲讲述了。你可以认为这两个是数据空间是独立的,但同时都在战区里边,能理解吗?OK,那此时此刻,我们就会认为代码啪掉到这里来了。
19:02
跑到这里来了,那么一跑到这个地方,它会把这个N1,这个值N1,注意听N1这个值就传给了这个这个test里面这个N1,此时此刻在我们这个test的占区里面也会存在一个N1,它的值会等于多少呢?它的值就等于你这个地方命这个N1里面传过来这个值,换言之也等于十。但是同学们可以看到,从这个图你们可以非常清晰的看到这两个N1,虽然名字都叫N1,但其实是。独立的。这就好比在教室里边有一个A教室,有个B教室,A教室里边呢,有个名,有个人叫三毛。B教室也有个人叫三毛,但是他们名字虽然相同,但是人是不一样的,一个是女的,一个是男的,对吧?说这一块是非常重要的,同学们理解了这个最基本的原理,那么同学们在理解函数这一块呢,就相对轻松而又容易了,此时此刻他又执行了N1等于N1加一,此时此刻相当于说N1自己加了一把一,OK,这个时候变级了,变11。
20:13
变11,但他变完11过后呢,他执行的这句话叫format print l,这么他输出了一句话叫test,什么玩意等于N1,此时刻在我们的终端里面就会输出这样一句话。执行到这句话的时候,我们的终端会输出test n等于C。当他执行完这个函数的时候,注意听,同学们又要注意听一个重要的此时此刻T的函数,它不是已经执行完毕了吗?那这个时候我们的编译器会怎么处理这个玩意儿呢?注意当它执行完毕过后,如果有返回语句,则返回,没有返回语句,那么这个就结束了,就说这句话执行完了就没有了,没有的话它又回到原先这个位置,因为你是从这这你你原先是从这执行调用这个test的吗?当他执行完了之后,它又回到这边来了,我们可以认为有一个CPU的一个一个东西在在不停的进行调度。
21:12
那么回到这里过后。辞职了,这个就还有什么呢。消失在人间。没了。谁把它消失的编译器会回收这个空间,因为你的站已经没有用了,就好像我们用完一个工具,我们再把工具还给别人,那么手上就没有工具了,能理解。好,当他回到这里来的时候,他继续往下执行这句话,哎,这句话是不是也是输出一句话,说什么may里面的N1,但是同学们注意看,Main里面是不是也有N1 N1是不是还还在呢?这个站是不是还没有死啊,没死此这个这个地方N1在等于多少呢?朋友们。等于多少十了解完事,此时此刻这句话执行完毕过整个整个这个站,这个主函数也就执行完毕,整个主函数程序完毕过后,代码这段也就没有了,整个内存分配的这给他分配给这个我们的应用程序,呃,给我们这个程序分配的这个空间也就全部。
22:12
被回收了。能理解,所以说这个时候当我们执行完毕这段代码的时候,我们的终端会输出两句话,一个是test的N等于11,一个是面N1等于十,理解,那么朋友们来,我们看看结果跟老师分析的对还是不对。Go run,我们的test,而不是test啊。Go。让运行。我们运行过后呢,我们发现结果跟我们分析的完全一致,大家看这里。理解,你看这里面是不是11啊。这边是不是十啊。OK,同学们,通过这个分析,我相信同学们啊,对函数的调用,它的机制呢,会有一个相对本质的一个认识,本质的一个认识,好在这里呢,我们再总结几句话,对这个代我们再总结几句话,啊把这段代码,我先把它放在我们的笔记里面去再总结。
23:10
来吧,刚才呢,老师的这个分析以及代码,我就把它放在笔记里面去了。来,各位朋友。从这里我们拿下。对不对。放到这儿。放到我们这块,然后呢,我对上面这个图片这个地方我再做几个说明,对。上图的说明有几点需要同学们引起重视,第一点,第一点我们可以看到。在。调用。再调用一个函数时。会为该函数开辟,开辟或者叫分配都可以啊,分配分配一个新的战区,新的空间吧,新的空间你可以理解成啊,你可以理解成刚才老师画的这个图,诶这个图其实刚才刚才这这这这这个地方还是比较重要的啊,就这个战区还是比较重要的,那我们还还把它保留一下好不好。
24:11
还把它保留一下,这个呢,大家看起来比较轻松一点,我要保留一下,大家可以看看,看的比较明白。不然辛辛苦苦画了一个图怎么样啊,自己给撤掉了,浪费了啊,浪费感情了,来,走到这。我再把这个图重新截一把。我把这个呢,再放到我们的笔记里面去,没问题吧。好,这是第一句话,在调用函数时,会为该函数分配一个新的空间,你可以理解成是一个新的站,但是实际上不是啊,呃,新的空间,但是它会用什么呢?是这个这个编译器,编译器会会通过通过自身的处理。自身的处理。处理处理,让这个站这个这个新的空间,新的空间和原来的原有的和其他啊,其他的这个占的空间,其他的占的这个空间呢,进行区分,分分开啊,分界分开区分开来。
25:11
区分开来。这是第一个同学们要注意的,第二个呢,注意听,在每一个函数里边,它们的数据是相互独立的。在每个。在。每个函数对应的这个占中,占中他们的数据啊,他们的空间啊,数据空间,数据空间是独立的。空间空间速度的不会混淆啊,不会混淆在一起,混淆在一起,那当然有些同学老师如果说这里面有个引用变量呢,当然这有可能,如果你传了一个引用过去,那这个test和命令呢,它可能是指向同一个数据空间,这个我们后面再说,这个属于在在引用类型的时候在引入的东西。第三点呢,当一个函数调用完毕过后,这个为该函数分配的这个占空间呢,也会被回收,当一个函数调用完毕后。
26:10
调用完毕或者叫执行完毕都可以啊,都可以或者叫执行完毕。执行完毕。完毕,好。好怎么样操作系统啊,就会操作啊。操作系统会或者叫编译器都可以啊,就是就程序吧,我们简单说程序会回收回收或者销毁。销毁这个函数对应的,对应的这个占空间。占空间好了,只要记住。只要记住这三句话呢,我们再理解这个函数上面就相对轻松了,好,这是老师给大家讲的第一个案例,那下面这个呢,老师再举一个例,就分析不像刚才这么这么细致了啊,我就直接几句话给大家一过,大家就可以明白了。我们来看第二个,计算两个数,并返回一个,干上这个简单吗?非常的简单,来写个代码。
27:11
好的,那现在它要有返回值了,我们来再写一个函数,跟上老师的思路。一个函数。OK,那get some。Funk。Get。什么呢上我既然要计计算两个数的和,我必须会有两个数,对不对,那就是N1。TN2也等于int没问题吧,各位朋友,那要这个时候,因为我要干什么呢?我要把这个数算出来再返回去,因此呢,我有个return非常简单,我这样写啊,我第一次分布写一下以后呢,我可以把它合在一起了,N1加N2这句话什么意思?我把N1和N2加起来,再重新付给一个叫sum的变量。能理解吗?然后我将这个return。上,其实这句话啊,这两句话是完全可以合在一起的。
28:04
完全可以合在一起,这个看你的习惯,也无所谓高低。有些有些人说老师这两句话太麻烦了,我这样写行不行?N1加N2 no problem。你也你也可以写一句话,没问题,就看你的习惯,那老师为了讲课方便呢,我还暂时用上面这个相对来说代码更清晰的,就是容易容易更理解的啊,容易理解的这种这种方式,那现在的同学们看代码来吧。此时此刻,我再来写出一个上。哦,写出一个sum等于啊,我直接让他把这个值返回到这边来。好,这接收get上。好,我把这个结果输出来。点print l print。好,我在这里面也写个may上。等于多少呢?Some,好,为了让大家看的更清楚一点,我在这个里面也写一下,我说盖上里面的some等于多少?哎,同学们想一想啊,你们琢磨琢磨,这句话输出和这句话输出是不是一样的东西了?
29:10
为什么?为什么?因为你这儿有return。那return怎么理解呢?Return你可以这样理解,就是当他把这段代码执行完毕以后,回想这个图,回想这个图他执行完完毕后,我刚才讲过,如果有return语句,就会就会把这个return返回给调用者,这句话这么理解啊,注意听。给谁当有return语句时,当函数函数有return语句。语句时就是就是将。将这个结果,把这个结果返回给返回给谁调用者。调用者,也就是说谁调用我,我就返回给谁。再说一遍啊,即。即谁调用我?
30:02
谁调用我就返回给谁,就返回给谁雷。这么简单。那想一想同学们,你这是谁在调用,是不是在这儿调用啊,你在这调用,你在这调用,我就相当于把这个结果返回给这个地方,也就是说你可以完全认为你看啊,打个比方,我现在传两个数进去。比如说我定义两个数,一个是N3。这次我就直接传了,我就不不那么麻烦了啊,直接传十传个20。你就可以这样理解,十和20放进去,它一加等于等于30了吧,等于30,好,这个地方就应该输出30,没没没毛病,那么也就这个地方是return一个多少呢?其实你可以理解就一个30。因为他执行的时候,这个变量就被替换成具体的值了,然后这个30返回到这里反馈给他,你可以完全认为这么写成这个。是一样的。为什么?因为你执行完了个sum过后,其实就是相当于把这个结果返回这个函数了,那返回给他,你返回的是30,那相当于这个好,那你可以理解这么应该输出多少,必然是30。因此同学们看。
31:13
我这里也会是三十来,各位朋友跑一把,看看刚才老师分析的对还是不对。来执行一小把跑起来。我们可以看到结果,我们可以看到结果,诶,我们看这面有个问题啊,代码有个小问题。嗯,这个为什么啊,大家看啊,因为我在return的时候,我这边少了一个东西,我有个变量要写一下,这个地方就是要指定你返回的参数列表,待会我还我还会说这句话啊,我在做个解释啊,这个地方的n int啊,是返回的参数列表再保存一下。看代码有没有问题。同学们可以看到此时此刻代码就没有毛病了,对不对,那朋友们,我们执行一把,看效果。
32:00
来,先看一下。同学们看,盖上里面等于30。没毛病吧,是不是等于30 M上是不是也等于30,这两个值为什么又相同了呢?刚才为什么不相同?大家看到为什么了?因为你在这个地方把结果返回给人家了吗?那你这是多少?我我也我这也是多少了吗?能理解吗?好,同学们,关于这一个案例呢,老师就给大家讲完了,后边我们遇到这个函数调用的时候呢,我还会在需要注意的地方还会给他再说一遍啊,再提一下来吧,把刚才老师写的这段代码放到我们笔记笔记里面去,利于同学们今后的复习。好的。来,从这里开始放。啊,为了让大家练习,我没有直接给源代码啊,源代码我会放在那个我们的另外一个文件夹。好的。把这一放。
33:00
复制一下啊。好,然后呢,我们再来第27行,第27行开始截取。再放到我们的笔记里边去。没问题吧,非常简单。OK。好,这个呢,就是我们这两个练习题的一个说明,最后再来说一些细节的东西。再来说一个细节东西,嗯,同学们看到老师的这个地方有个叫written语句,刚才呢,我们用了,但是没有详细的说明对不对,说大家可能还是有点迷茫了,可能有些地方诶不太清楚是说了什么意思,来吧,我们看一下语句,那首先呢,看一下它的基本的语法。告函数中支持返回多个值,这一点其他语言编程,其他编程语言是没有的。其他的编程语言里面要返回多个值,往往通过数组来实现这个效果,但是在我们的go语言里面,它是可以直接支持返回多个值的。那待会儿呢,老师在还会做案例的演示。
34:02
呃,那么我们一个函数的一个带的一个基本语法是这样子的,同学们看一下这块我就直接说了啊,Fun是个关键字,函数名。行参列表什么叫行参列表?回忆一下,是不是就是我需要他传什么东西啊,返回值类型列表,就返回值类型列表,就是你有哪些返回返回值的类型给我写清楚,然后这地方就是语句,就是具体来说就是你这个函数要完成的功能,Return语句就是返回的返回值列表给我写清楚,如果这有多个呢,用逗号间隔就可以了。这边有两个细节需要同学们注意,第一个,如果返回多个值,在接收的时候希望忽略某个返回值,可以用下划线符号来表示站位。理解第二个,如果返回值只有一个,这个括号可以不写,但是如果有多个必须要写括号,能理解吗?
35:00
那同学们可以看到,刚才老师这个地方其实是有返回值的,你看我这里面就没有写括号,但是你写上也可以,你写上也可以,你看我把它括起来了,括起来过后我再一字行,同学们可以看到没有任何毛病。你看它仍然是可以的,但是因为你只有一个呢,一般来讲我们出于这种编程的习惯,GOGO的这个编程者呢,一般来说就不写了,但是有多个就必须要写哦,好,同学们,这是我们这个说明,那么现在呢,我们来举例说明了。现在同学们看我写的语句。Return语句理解来跟上老师的思路,我们给他一个标题三的意义啊,那么我们看一下它的基本语法,它的基本语法和说明,这块先给大家聊一下。刚才老师呢,已经做了一个说明对不对。这会儿呢,我们再举一个案例,演示两点。
36:02
好,刚才这这一段呢,老师就直接拿过来用了好不好,我这就不再啰嗦了。我直接把它把这一块内容先放在我们的笔记里边去。跟上老师思路啊,同学们,案例我们再举一个案例来,现在我举这么一个案例啊,来案例说明。情。请编写一个函数,函数可以计算两个数的和和差。并返回结果。看到这里,我要希大家写一个函数,可以计算和。还有呢,就是它的差没毛病吧,然后呢,把这个结果返回来。想想这个时候其实就是要返回几个值了呀,两个值,那这个时候呢,我们就跟刚才的写法要有一点区别了,来吧朋友们,写上这个地方的代码,来,我先定义,呃,我就直接写函数了啊朋友们。
37:03
我把这一块呢,要求先给同学们拿到我们的代码里边来,直接写fun get some some。And sub。啊,听这个名字就知道是干啥了,对不对,然后呢,老师就直接写N1INCH n2。Int,我这边都叫N1N2没问题啊,就是大家看到,因为它有不同的占空间,能理解吗?我要返回两个值,所以说用int int分开。这方就必须要打,这个地方就必须要打括号了,同学们,然后呢,空格来吧,我们计算一个和。和很好计算,N1加N2就是它的和,Subb也很好计算,就是N1减去N2就是它差。上。上。
38:00
了解好,写完了,写完过后呢,我们来接收一把。调用,大家看,我们怎么去调用这一个可爱的函数呢?非常简单,同学们看。我们这样来接收了啊,同学们注意听注意听,呃。我我这样写SUB2。逗号。SUM2啊,然后那个sub,我们这样也可以,这个看你的看你的名字命名B,就说我把第一个结果叫RESULT1,第二个呢叫RESULT2,没没毛病吧,然后等于。等于什么呢,Get。上就这个函数我就不写了,把这块呢,拿到我们的笔记里面去,我传入两个值,一个叫一,一个叫二,同学们想,此时此刻这个等于多少?等于多少跟这里。再返回什么。和。对应它。第一个值就是第一个,第一个返回的值交交给一了,第二个返回的值呢,交给RESULT2能理解吗?那也就是说大家可以推测出来我们的。
39:07
RESULT1其实它是等于和应该等于三,而我们的RESULT2它是等于多少呢?那就是一减二负一。理解好,那么这个时候我们打印出这个结果,给大家搂一眼。具体讲,RESULT1,我们直接让格式化一把啊,同学们格式化一把,Re result1等于V。RESULT2。等于。这个到如果好看,我换一个行,直接输出一。和RESULT2。来吧,各位朋友,直行,小板他在吗?走起来。啊,这边有个问题啊,这又写错了,是不是我多写了一个N呐。多些人,因为现在我没有用那个IDE工具,所以说这块呢,呃,全是靠自己代码写的,如果有IDE工具啊,它就会很快的告诉你。
40:01
那跑起来。看效果。我们可以看到RESULT1呢等于三,而RESULT2等于负一,跟我们分析的完全一样。好了,这是我们刚才讲的这个案例,那么还有一个细节我要多说一句,好,我把这段代码先给大家拿过来好不好?先把这个老师写的这段代码呢先放在我们的笔记中。好,这个地方是它调用的一段代码。好,我把它框起来,看清楚没有。我把它框起来了啊,我把它框起来了。那么我把它框起来过后呢,把它放在这里。另外还有一段代码,就是这个函数是怎么写的,我把它也拿到笔记里面来,我们函数是这样写的。是不是是不是这样写的呀。是这样写的,那这里面还有一个细节要跟同学们聊两句,有个什么细节需要同学们注意呢?就是有些在某个情况下,你可能只想要其中的一个值。
41:06
打个比方,追寻这句话也很重要哦,比如说你返回的是一个和sum,还有一个叉sub,但是有可能我只想要其中的一个值,比如说我想要和,我不想要差,或者我只想要差,不想要和,也有可能。那怎么这个时候怎么处理呢?注意听下一句话,注意细节。一个细节说明。细节啊。细节说明什么呢?就是可以使用,大家看到在这里面我说了一句话啊。可以使用。可以使用这个下划线来占位。希望忽略某个值可以使用下划线符号来表示忽略,那我给大家再举一个案例好不好?再举一个案例,相当于说这是这是案例一吧。这个呢,我们来一个案例二好不好?案例二案例演示二。
42:03
那现在呢,我们把它放到笔记里面做好,那举例说明。Candy。嗯,大家主要是看怎么调用。来吧。如果我只想取这个和不想要这个差,我怎么写呢?这样写。好,我再调用一次,我来个RESULT2,那这个我摆成三吧,好吧,等于好再把这个函数调用一次,大家知道函数可以反复调用啊。这个时候大家看也是没问题的,这个时候我只拿到一个和了。啊,我只拿到一个叉了。但这样子调用也是没毛病的,我自己输出一下。来吧各位朋友,RESULT3等于多少啊?说出来。这个时候你看语法也没有报错。你看语法有没有报错。比方说为了看到以示区别,我把这个干改成三,这个改成九来执行吧。
43:01
跑起来,我们可以看到RESULT3就应该等于负六。没毛病,没毛病,但是有时有些同学老师,如果我两个都不想要呢,也可以。这样也可以,那两个都不想要,相当于说这样调用一下。对不对,那你不是吃饱了没事干嘛,你这地方还有问题啊,干了还不行,这样还不行,这样的话,因为你如果两个两个这样掉的话呢,就相当于说两个都没有值,没有值的话,这个就是这样就可以了。这样也可以,但是这样没有意义对吧,这样没有意义,这样写的话,其实相当于你这样写就等价于这样写了吗?掉了不要值吗。对不对,没有意义,所以说呢,我只说这个说法啊,说这个说法就也可以这样去用,明白吗?好了,同学们,我们把这个刚才恢复一下。好的,RESULT3。好朋友们把这个呢,咱们也打开。如果忽略,咱们怎么去调用。把这句话呢,放到我们的笔记里面去。
44:01
打起精神。好,注意听老师讲课啊,好的这个细节好,同学们,那通过刚才老师的这一段讲解了,我们其实就把函数的一个调用机制给大家做了一个说明,这里面我强调的就是这个图很重要,能理解吗?就说你一定要把这个图搞得明白一点,就是为什么它这个值,这里面有几句话很重要啊,大家看在调用函数时会给该函数。分配一个新的空间。编译器会通过自身的处理,让这个新的空间和其他战斗空间区分开来。很重要,因此在每个函数对应的占中数据空间是是独立的啊,这写错了,独立的。独立的,独立的,不会混淆。不会很小,当一个函数调用完毕以后,或者叫执行完毕后,程序会销毁该函数对应的占空间,有这个看占空间就被回收了。OK,嗯,然后呢,我又举了一些小案例,对不对,举了一些小案例,加深大家对这个东西的认识,好,我把这段代码稍微的缩小一点啊,这个太占空间了。
45:05
挪一下。排下板啊下板。OK。好的,还有return语句我也讲了,然后它这是它的基本语法,这老师举了两个案例,加深大家认识。好,那关于函数的调用机制呢,老师就给大家介绍到这里。
我来说两句