00:00
各位同学,下面呢,我们再来看一下函数在使用的时候需要的需要注意的事项,以及它的一些细节讨论,那么函数要注意的注意的事项和细节呢,比较多啊,大概呢,我总结了有13个点。所以说我们把它分成两个部分展开讲述好不好,我们现在看第一部分有一些呢,其实是前面已经讲过的,只是在这呢,在系统的过一遍,有一些还没有讲到的呢,我会举一个案例给大家详细的介绍,我们先来看第一个。第一个大家看到这里函数的行参列表可以是多个的,这个没有什么可说的吧,就是它的行参可有多个,而且返回值列表也可以是多个,也就是说返回值呢可以是多个的,比如说我们前面写了一个函数,还记得吧,我们让它返回了两个数的和,同时也返回了两个数的差,这就是返回值列表可以是多个的。说明第二点呢,行差列表和返回值列表的数据类型可以是值类型,也可以是引用类型。
01:07
也就是说,他返回的类型可以是任意的。没有什么限定,可以是整数,也可以是字符串,也可以是一个map,也可以是一个数组,OK,好,这一点大家注意一下。第三点函数的命名规范呢,它还是按我们以前说的命名规范来做,还有一点就是首字母不能是数字。这个是不在前面已经提到过这个概念了,就是标识符在命名时候的规范,老师已经讲过了,对不对?还有呢,就是首字母大写,则该函数可以被本包文件和其他包文件使用。我们在。前面的哪一点讲过这个这个东西啊。哪一点讲过这个知识点,是不是在讲我们包的注意事项?在讲到包的注意事项和细节的第三点,我们提到过这个概念,就是为了让其他的包文件可以访问到本包,本包的函数,函数的名首字母需要大写类似于其他语言的public。
02:11
这样就能挎包了,能理解吗?也就是说这个知识点。这个知识点,现在老师标出的这个知识点其实在前面讲过了,那如果说我们首字母函数的首字母是小写的呢,同学们。如果我们首字母是小写的,则只能被本包文件使用,类似于private说,这个案例我就不再举了吧,同学们,因为前面咱们已经讲过了,再反复说也没有意义。如果同学们忘掉这个地,这个地方到底是怎么举的例子,请同学们打开笔记的第三点,这地方我做了详细的介绍。同学们再去看一下好不好?第四一点,函数中的局变量是局部的,函数外不生效,这点呢,我要举个例子说明一下来吧。把前面的四点我们整理到笔记里面来。现在我们讲的是什么呀?就是函数。
03:03
使用的注意事项和细节。来吧,放到这儿。函数。函数的函数使用的注意,注意事项和细节讨论。细节啊,这个细节。细节讨论。那我现在把它整理到这块,大家跟上老师思路。刚才呢,已经从整理了四点,我们先把它板书一下。对吧,第二点。有些,因为前面已经讲过的呢,我就不再举例了,好吧。前面的三点说过了。第四点呢,我要举个例子。把它整理一下,板书一下。诶,在这里我们来举个例。案例说明函数的变量是局部的,函数外不能生效,什么意思来新建一个包包DEMO?
04:04
DEMO。Function。DEMO0几了呢?应该是零五了,我记得是不是应该是零四了,对零四来新建一个文件,跟上思路main.go没问题吧,同学们。那前面这一部分相同的呢,我仍然把它拷贝到我们的笔记里面来啊,拷到代码里面来。面组函数写进来。写进来,然后呢,我们来看看这个刚才讲的这个知识点。好,我把这个知识点呢,啊,把这个细节。给它先放在我们的Vs code里边去。我们举个例子,比方说这里我有一个函数叫test函数,没问题吧?那在这里边儿呢。在这里边我定义的定义了一个变量叫VRN1NUMBER等于十,各位这个N1变量的作用范围呢,只能是在test里面,在别的地方用不了。说明一下N1。
05:07
N14。是test函数的局部变量。局部变量。只能。只能在test函数中使用。Test函数中使用。那也就是说,如果我们在这个main函数里面,我们是用不了这个N1的啊,如果你这样用它会报错的,这点其实在前面我们讲函数调用机制的时候呢,其实这个是体现出这个特点了,有些同学们可以根据原理来推导啊,不是说每一次都要老师分享讲一遍。但是需要提的时候呢,老师还说说你在这里面用不了N一看N1。等于你在这边用肯定是要报错的,你看N1,他他直接告诉你N1没有定义,大家看效果。看我们保存了啊,保存过,我们看他这提示一个错误,他说on defend n1。
06:01
能能理解这意思吧,好,这点就这地方用就是错的这里。这里不能使用N1。因为,因为N1。因为N1是。是test函数的。函数。的局部变量。对吧,所以在里面用就错的了,好我把这个呢给同学们粘到这里来。这是关于这个知识点的一个说明的案例。把它放到笔记里面来,没问题吧,同学们。跟上思路,我把它放好。那下面呢,我们再来看第五一个细节。第五个细节。第五个细节呢,老师要讲的就是这个点了,基本数据类型和数组默认都是值传递。及进行,只拷贝在函数内修改,不会影响到原来的组,这边要注意就是哪一点呢?就是这个点有点意思。
07:06
我把它先拿过来。同学们。就这个点。基本数据类型是值传递,这个很好理解,但是呢,数组就是这里面说的基本数据类型。还有宿主。数组都是直传递。值判定呢,其实就是进行的值拷贝,在函数内修改呢,不会影响到原来原来的值,那有些同学说了,说老师那个那个数组不是我们现在还没学吗?那你这先先提这个干什么呢,我因为。我们这有些听视频的同学,他是有编程。编程基础的,有些同学是有编程基础的,在其他的编程语言里面呢,这个数组往往都是引用类型的。往往都是引用类型的,比如说Java Java其实他在这个传递的时候,它是引用传递。所以说它在函数内呢,是可以修改到函数外的这个数组,但是同学们注意再强调一点,在功浪里边基本数据类型和数组都是直传递。
08:10
也就是说它不是引用传递,那么在函数内修改呢,不会影响到原来的值,我这个地方给他举个例说明一下,这边跟上思路啊,因为数组呢,大家还没有,呃,还没有去,呃这个去使用过,所以说这这个地方我先把这个概念,把这个把这个结论抛给大家,讲到数组的时候呢,我们再举例,我现在举一个基本数据类型的案例,好吧,其实前面已经讲过了,只是在这再把它统一的系统的说一遍,能理解吗?好比如说现在我有一个函数。比如说我这里有个函数,注意听fun test202,然后呢,这有个N1,我我换一个字符串吧,一样的啊,比如说这有个name name string。然后呢,我上来给我把这个name string,那这样子还是用整数比较好说啊,用整数比较好好说in n1。
09:05
当然呢,我把这个N1做了一个处理,做了一个什么处理呢?N1我加了一个十。是吧,其实在前面已经讲过这个知识点了,比如说我这有个N1。我这有一个,比如我换个别的变量叫number number。啊,这样子吧,就N还叫N1。我给他来一个20,然后呢,我调用TEST02,把这个ne一传进去,然后呢我在这里输出。Prince。注意听啊,同学们print,然后呢,我在这里面输出了一个main里面的这个N1。它输出来N等于多少。对吧,在这里面呢,同学们看我在这里面也输出一句话。我在这里面也说出一句话。这边是我们的TEST02里面的N1也输出来。
10:01
保存一下,大家看在这里,我在主函数里边。定义了一个N1变量,我传给了这个变量啊,这个地方还。啊,他说没有用过,没有用过,现在把它注销了,好吧,把把它注销了,大家看这个主函数里面有个N1等于20,我传给了。传给了这个TEST02里面这个N1,那么根据前面咱们讲解的这一个函数调用的机制而言呢,会开辟一个新的站叫test的零二,这个站里面会有新的变量N1,因此这个N1的变化不会影响到外面这个N1,也就是说它们两个是独立的,是不是根据前面函数调用机制语地制机制就可以把这个搞清楚啊,只是我在这再把它系统的说了一遍,来跑一遍。跑起来吧,同学们。我的CD到。上级目录再CD到我们的这个fun demo04里边去,没问题吧,Go run里面的面点go跑起来。
11:04
跑起来。同看效果,这个时候你会看到两个值是完全不一样的,你看T的零二里面呢加了一个十,但是main函数里面的N1仍然是这个20,这也就是说这个概念就是N1传到这里面,它进行一个直拷贝,所以直拷贝就是说他会把这个N1的十拷贝给这个test的002里面这个N1。那么两个就是相同不同的变量啊,当然你名字不同就更不同了,我这名字相同,他们都还是独立的,如果我这写了一个N1,比如说我这边量是叫做number。这把我传的一次number。我这传的也是number,这我打印的也是number,那更更不相同了,对不对,他还是把number这个数。20拷贝给这个N1,然后这个N1呢,他拿到就是20,但是达到20过后,他加的是这个TEST02里面的N1,因此对这个number呢也没有任何影响,能理解吗?好,我们再来试一下。
12:08
就是我这反复其实就在阐述一个问题,什么呢?就是基本数据类型,包括数组,它是一种只拷贝的方式来进行这个,呃,参数传递的。来吧,我把它运行一下,再看一下,请看效果。请看效果,仍然是一个30,一个20,对不对?好,同学们,把这个案例呢给同学们放到笔记里面去。理解了啊,我这举的是基本数据类型,数组也是一样的。来吧,放到我们的笔记里面去。不说了啊,同学们看基本数据类型和数组都是直传递进行了直拷贝。那么第六点我们再来看。如果我们真的希望函数内的变量能够修改,函数外的变量可以传入什么呢?地址?函数内以指针的方式来操作变量,这是可以的,从效果上来看呢,类似于引引引用传递。
13:05
类似语音引用传递,因为引用传递这个现在我们还没有讲过引用传递的其他的数据类型,比如说map啊,还有这个。切片啊,我们还没讲过,那那现在还没办法举这个案例,所以我现在呢,只只能先用指针的方式来达到一种引用传递的效果,就是我直接传地址的方式的话,就可以来改变外面的值了,来我们来看一下。举个例子。就还拿刚才案例说话,如果我们希望函数内的变量能够修改函数外的变量,那当然我这指的是基本数据类型和数组,如果你本身就是引用传递,那当然这个就不说了,对不对?那肯定就本身它就可以直接修改,那就不说了,我这里指的是什么呢?哎,指的是。指的是默认以。以直传递的方式直传递。
14:04
值。传递。的方式。方式的这个变量。那那个数据类型,数据类型。呃,数据类型就是如果我们希望函数内的变量能够修改函数外的变量,我们指的是默认以值传递方式的数据类型啊,比如说前面讲的这个基本数据类型和数组,那么我们我们希望干什么呢?我们可以传指针的方式来来达到这个,这个效果就在函数内也可以给他改了,那我们来举个案例。同学们来打开这里。来怎么写呢?我对上面的代码做一个修改。我写个T03好不好?泰森零三。好,这段代码我先把它注销了好吗?然后呢,在这里我在写的时候就要这样传了,我传地址,地址的时候这边是指针。能理解,这就变成指针了啊,指针这里N1。
15:03
就是。这个类型的。好。好,这个时候呢,我们看怎么修改它呢,来还是老规矩,把前面这个NUMBER2复制一份,然后我在调的时候要这么调了啊test。啊。TEST03。然后呢,我传了一个地址进去。Number好,这个传一个地址进去呢,这边也接收到了,接收到的时候,我在操作的时候,这样这样操作了啊。能理解吗?好,这里面这个N1取的时候,当然因为它已经是这种指针类型了,所以说我在取它的值的时候呢,要这样去,关于指针的这两个操作符,我我讲过啊,一个是取地址符,一个是取这个指指针,它指向那个值的这个运算符我都讲过,前面在基础的时候讲过,对不对。
16:02
好,那现在呢,我们来运行一下。我把这个也打出来哈。这边看。好,同学们看,这个时候同学们可以思考一下,如果我传了一个地址给到这个N1。给到这个N1。给到这个一,那么这个时候他们操作的是就是同一个数据空间了,于是乎这这边改变了,这边的改变,这个函数内部的改变会直接影响到外面这个number的改变,也就是说这个地方会输出一个30,而这个地方呢,也会输出一个30,待会儿我再画一个示意图给大家好不好?来跑一个吧。来,跑起来,请看效果。我们可以看到两个都变成30了,原先一个是30,一个是20,现在两个都变30,为什么呢?因为传的是地址,那如果说我们画一个示意图,原理图来看的话,它应该是这样子的,来同学们跟上老师思路,我画一个原理图帮助大家理解。
17:06
我就画一次啊,后面我就不反复画了。可以这么理解,同学们。听我说还是老规矩,这地方呢,有一个内存。就是说这边有一个内存,那么我们姑且就只用占区就行了。这是内存啊,也不用分那么多了,直接叫内存就行了。那我们的代码呢,就从这里开始执行了。是不是从这里开始执行?能理解吗?执行,那一执行的话呢,根据我们原先讲过函数调用机制,就会产生一个main的空间。我们姑且白叫命战。是吧,内战里面呢,就会有一个number值,大家看清楚number。Number呢,它会有一个值20。二二十当然这个number本身它是有个地址的啊,这个值本身会有个地址,我我以前在前面是不是讲过,就算是一个。
18:08
因基本数据类型,它也也有个地址,这个地址呢,我们可以把它打出来看一下。这个例子我们可以把它打出来看一下,来同学们看。我把这个例子拿出来给他梳梳下看一下啊。我们来print。F。我们输出number的地址。大白的地址是多少呢?我们这样输。好,我们现在执行一下,同学们看。就这个number这个本身它是一个地址,这个地址呢是这个。是他吧?好,我们姑且认为在这个地方就会有个弟子。就是它的这个空间本身会有个地址,能理解吗?好,当他这样做完了过后,它调用test的零三,看清楚没有TEST03 test的零三呢,也会开辟一个新的站,这个根据我们以前讲这个原理,它会开辟一个新站。
19:07
好,这个站呢,或或者叫独立空间都可以啊,我这为了方便,我就直接叫做泰山这个站。这个站里边呢,会得到有一个变量,这个变量叫什么N1,但是这个N1注意听这个N1已经是一个指针类型了。这个N1已经是一个指针类型了,所以说这个N1它本身会指向一个空间,这个空间里面存了一个地址。叫他。能理解吗?能理解吧,也就是说这个N1它它有一个空间,它会有个空间,它是个指针类型,它存了一个什么呢?这个地址,这个地址呢,它指向了就他。当然有些同学可能会问到说老师你能你能告诉我这个N1本身它有地址吗?N1它是个纸质类型,它本身还有个地址,也就是说如果我们说的再明白一点,你这方还可以打印出来一个东西。
20:07
这在其前面,以前我们是讲过的,就是N1的地址。它这个就是它虽然是指针类型,其实它本身还也它也有地址对吧,比如说你像这样取。N1。N1就说它本身呢,也也会有个地址,N1也会有地址,因为它是指针类型,但是它本身也有地址,我们输出来看一下。显然,这两个地址肯定是不一样的。对不对,显然他是不一样,大家看诶,为了为了好看啊。为什么我这老是这样子呢,来吧。V。小写的V。一个N这样子,我把它来一个换行好吧。来一个换行,这样看起来就比较轻松一点,跑起来。好,同学们可以看到我们说这个N1,它有一个地址,它的地址是这个,看这是两个不同的地址。
21:00
就就类似于这个地方,我如果换一行啊,类似于它本身N1的这个存放。地地方呢,它有个地址,但这个这两个地址显然是不不是同一个地址,看他指向它。就说N1是一个指针类型,有一个空间,这个空间呢,地址是0X什么什么,这个空间里面放了另外一个地址,它指向了N1NUMBER这个这这个地方。好,然后我们回到这里来,这个时候进到这里面的时候呢,N1因为有有指向了,所以说星号N1,星号N1其实就相当于返问到这个20了,能理解吗?就星号。星号这个代表是取值,取谁的值,取它存的这个地址所指向的那个值,那就是20,这方也是20,就是20加了一个十改变,它就把这个值给修改了。因为它是用。这个取值的方式来操作的,所以他就操作的是这个地方,因为它这个指向是指向在这嘛,对不对,好指向这做完了过后退出。
22:08
退出到这了,当然当他整个这个做完了以后,同学们根据以前老师讲解的时候,函数调用完毕以后,这个占空间显然就没有了。没有就没有呗,无所谓。但是他他在他在退出之前。同学们是不是他在他在这个把这个操作。30做完了以后,他输出了一句话呀,是不是他这这输出了一句话什么什么什么,这句话是不是太的03N1里面是星号N1啊。星号一是不是就把30打出来了,因此他在这里面其实就本身就会输出一句话,就是同学们看到的这句话。就是这个控制台里边终端。终端里面就会输出T03。里面的N1等于多少呢?等于30,因为它是用取值的方式来取到N1就是它指向的这个数据的,所以说他这就等于30,当他把这句话,当他刚才把这句话打完过后,这个函数才算执行完毕,执行完毕他就回来了,回来过后呢,这个站就没有了,但是留下了一个输出了一句话。
23:19
好,当然这个线也就没有了,输出完了过后呢,啊,他又继续执行这句话,注意这句话实际上是在这个命命战里面,命这个站里面执行的也是输出了与什么什么话,大家看这个话里面输出什么呢?输出是number,那number现在是多少,就是30,因为因为这个30呢,它就是一个普通的基本的数据类型,所以它不需要。取值那些符号了,就直接输出就行了,这时它输入的是may,里面有个number等于多少呢?等于也等于30,因为已经被刚才这个函数修改过了,对吧?能理解吗?好输,最后输出结果就这样子的。好,这就是老师给大家分析的一个原理图,希望大家能够有印象。好,为了便于大家复习,我把刚才画的这个非常好的一个图撤回去。
24:09
我觉得这个图很很关键啊,同学们。这个图非常的棒,可以这么说啊,这不是老师自夸,这个图你要把它理解了,过后呢,说白了,你把这个传值包括函数的调用机制理解的更加透彻了,比前面还要透彻一点。好,这边输出也写出来,每。里边呢,有个N1,有多少三,哎,不是N1,是number,好,同学们,这个就是老师讲的第几个细节,第六个细节,同学们注意一下来,我把第六个细节的示意图也给同学们拿到笔记里面来好吗?好,我放到这了。OK。好,这就是怎么去让基本数据类型或者数组达到一种引用效果的使用的方式。好,这是第六点,最后一点,第七点,第七点也是非常重要的,在构函数里面,它不支持函数的重载。
25:11
他不支持函数重载,为什么要单独提这一句话?因为有很多的编程语言里面,它是支持函数重载的。那什么叫函数重载?对于我们初学者还没有太多的认识,我举个例子。比如说大家看这是一个T的零三。你就不能这样写,说老师我我这样写简单一点啊,写个TT002吧。很多的编程语言里面可以函数名相同。然后呢,变量这个形参不同,比如说我多一个行参。很多编程语言里面这个T02。这有个T02,他们通过行参不同呢。形成的个数或者数据类型不同可以区分,但是我告诉大家,在构里面它不允许这样写。
26:01
因为这个现象就是TEST02这两个就大家看到的啊,注意尤其是初学者可以注意一下。这是TEST02,这个也叫TEST02,有很多语言里面,它支持函数名相同,但是只要你这个行参的个数或者数据类型不相同呢,他就认为这个是正确的,这两个是这两个是不同的函数,他认为,但是我告诉大家。这种写法。这个所谓的重载在勾浪语言里面它是不支持的,你保存一下。他马上就会报错。大家看他马上就会爆出。为什么呢?因为后面我们会讲,在勾浪里面,它是支持可变参数的,而且它还有一个叫做空接口的东西,其实它完全可以达到这种效果,也就是说go语言里面呢,它是用另外一种形式来实现这种函数重载的,能理解我的意思吗?也就大家记住一句话。
27:00
Go语言里面不支持传统的函数重载就可以了,就这种写法是错的,能理解哈,我写到这来。所以这种写法它是不允许的。即这种写法是不正确的。错的。啊,他认为这个是重复定义。这样他会认为TEST0,二这两个是相同的函数,它会报什么呢?它会报一个重复定义的错误。不支持go,让不支持传统的传统的这个函数重载。啊,重载。从这A。这写错了对吧,重载啊。不支持,所以说这样子他汇报什么汇报告。汇报什么呢?函数重复定义。函数重复定义了。写完。好,我把这句话呢给同学们放到笔记里面来。
28:01
OK,加深一个认识,好吧。加深一个认识。好了,同学们,那关于呃,就是我们的第一部分的函数使用细节和注意事项呢,老师先给大家介绍到这里。后面呢,我们再说其他的。
我来说两句