00:00
我们来举几个例子来加强啊,我们举举一个例子吧,啊,举一个例子来加强一下应力函数的使用,大家看这里。好,同学们看这里呢,呃,它说编写一个匿名函数可以返回两个整数的和,并输出匿名函数的类型啊,这个对我们来说太简单了啊,我这整一个变量F1等于,这个就是一个匿名函数的行参,然后呢,一个符号大括号包起来,里面写上我们的东西。那这个时候这个F1呢,我们就可以是一个匿名函数了,那调用的时候通过这个匿名函数传参就行了,如果你不传参数。它就代表输出这个类型,你传上参数就代表调用这个匿名函数,OK,非常的简单,我这个就不去运行了啊,很简单,一个代码我就直接拿过来放,这就OK了。好,同学们,这是一个小小课堂案例。小小的课程案例我写到这里来,然后直接把代码给他放过来,因为很简单,所以说我也不去运行了。
01:06
好,把代码直接放到这里好了,那逆面函数的一个小案例就说到这儿,那下面呢,我们继续来看下一个话题是什么呢?高阶函数。那么高阶函数呢,我们前面讲过,但是呢,还有些地方没有讲到,比如说高阶函数呢,除了可以接收一个函数之外呢,它还可以返回一个函数,诶这个点是它的一个很重要的特色,我们先来看高阶函数的基本介绍。那么能够接收函数作为参数的函数呢?我们就称之为高阶函数啊,它有个名字叫higher order function。可使应用程序更加的健壮。而你比如说现在我这里写了一段代码。这段代码呢,目前对于我们来说应该很轻松了,我们简单的看一下。这里是一个test函数,它可以接收一个高阶函数,接收一个函数。
02:06
这个函数的类型是,呃,传入double,返回double,要匹配这方传入一个普通的参数,好,那么这个时候在里边呢,我去调用了这一个传入的函数。去执行它。好,那么这里为了测试呢,我专门写了一个sum。这个函数,这个函数呢,就是接收了一个double,返回一个double的案例,最后调用的时候很简单,就是test把这个函数传进去,再把6.0传进去,那么这个6.0呢就传到了N1,这个N1又传给了我们的这个传入的函数去执行。哎,你看这个逻辑呢,还是很清晰的啊好,这个呢,以前因为我们这个讲过,我把这个代码运行一下就过了啊下面呢,我们把重点放在没有讲过的地方。
03:02
好,同学们,我给大家运行一下高阶函数的案例。Hi higher order。Order方式。高阶函数。写到这里来,同学们走一个组啊组函数代码呢,我就往这一粘就行了啊好呃,我们分析一下这个东西啊,这边肯定就是这样子的,把这个6.0传给了some。啊,上到这来了,在在在底层里面test里面去调查了。啊,也就是说这个F1呢,它F它其实指向了我们上午这个函数的地址,然后呢,你去调的时候,其实它会走这段代码,那么这个N1就从这个6.0传进去,大致的逻辑应该是这样子的,就是6.0。传给了N1。没问题。然后六点传一过N1过后呢,这个sum,它把这个sum这个这个是个有个地址的,相当于这个地址呢,传给了这个F1。
04:06
OK,那么到了这个执行的时候,执行这个态势的时候呢,这个F1的地址,因为它指向了它,所以说它会到这边来执行,然后这个N1呢,会被传给。这个位置,所以最后相当于执行了这句话。执行完了后,这个结果呢,返回给我们的这个test的用那个类型推导,大致流程是这样的,第一步传这个第二步,传这个第三步。把这个传给我们的NN1最第四步执行,最后这个结果返回给。我们的test啊,大致就是这样一个流程,好,也很简单,现在这个结果呢,就很显然就应该等于一啊12.0。那肯定等于12.0,那么我跑一下。好,我跑一下。走一个。好,代码写完,那这边有一个问题说老师这个高阶函数里面能不能再去调一个函数呢。
05:04
什么意思?比如说我在这里做一个小小的扩展,怎么扩展呢?比如这个F1,这个我希望对F1传递的N1先做一个呃,取模的操作。假设啊,我做一个不不做取模吧,先加一啊取,或者说取模过后再传给这个F呢,可不可以呢,这个地方我们来做一个小测试啊小测试那假如我这里还有一个函数。这个函数是干什么呢?就是把double转成一个int,再返回它的一个取模的值,假如啊,我们写个F2。就是取魔的mode。Mode,一个函数,假如呢?我仍然接受一个double。好,但是呢,我返回的是一个int值。
06:00
那我怎么做的呢?假如我就我们就玩一把啊,就d to in。然后呢,磨磨。啊,比如说摩尔啊,摩尔这个代码肯定是正确的,然后呢,我在这个test里面,假如我想同时使用两个啊,比如这我接受一个F2,那它传进来是个什么呢?它传进来是一个double类型。哎,它传进来是一个W。传播的是个大。转过来是一个double类型,然后这个double类型呢,我返回的是一个什么类型呢?返回是个int类型,好写完。那这个时候我想这样玩,就是F1F一再进行,再进行这个去操作的时候呢,先不着急,先把这个F1传给我们的F2先预算一下。啊,大家看看这个行不行啊。啊,这个时候我们把这个N一再传进去,那传进去这边我们再加一个东西,就是这个地方呢,传入一个mode。
07:03
可以。也就是说我们这个地方呢,不能认为说只能传一个高阶啊,不能不是不能认为说只能传一个函数,我们还可以传数多个,而且函数之间还可以调用,那这样子的话呢,它的功能就会扩展的。更加厉害。啊,比如说我们在这里面高级函数里面使用我们的对集合的map啊,Reduce啊,Flow呀等等,那可以继续做,因为你将来做的时候,如果用到匿名函数,你可能传的不是传输的不是一个函数,一个能传多个对吧,那这样子呢就很OK了,那我们看看这个结果应该是等于多少啊,我们先不要运行,我们先在尝试着自己推断一下应该是多少来走一个首先。F他把这个F86.0传给了这个F2,就他F2是谁是mod。那Mo的它把这个6.0先取一个整,再磨二,应该等于多少呢?
08:02
等于零,那就相当于是等于零对吧,等于零的话呢,诶,那相当于这个零再加里最后返回是零点,所以这样子的我们就做完过后就变成0.0了,变成0.0,只要是0.0,说明我们这个代码是正确的啊,我们就说一个机制问题。好,我们执行完了过呢,我们发现的确是0.0代码是正确的,好我就说一下这个函,一个是我们高阶函数,可以接受多个啊,这种匿名啊函数,同时呢,函数之间可以相互调用,我就讲了一下这个逻辑啊,那我这假如写个5.0,大家知道是多少吗?那就是2.0,能能理解吧,肯定是2.0,好要看得懂这个代码啊,同学们啊,看到是2.0,好老师就说到这里了啊,所以要看得懂这个代码,不要说诶怎么函,因为函数里面再掉了一个玩意,啥意思,对吧,这是完全可以的,它是支持的,好我们讲了这么一个高阶函数的基本使用。那紧接着呢,我们再来讲一个高阶函数的另外一个用法,也是相当重要的,由这种用法呢,引起了很多这个新的语法现象,你比如说函数的颗粒化,函数的必包就是由这个特性产生的。
09:16
什么特性呢?就是高阶函数呢,不但可以接收一个函数,它还可以返回一个函数,诶这个就很厉害了,所以说我们这个函数为什么说变成了一等公民呢,它就跟一个变量一样,它既可以接受,它也可以返回。那这个就很厉害,那我返回这个东西,我还可以继续执行,诶,那同学们看这么一个小小的案例,我这里写了一个minus X y。啊对,就是呃对XY求求这个求求差,那大家看到我这个代码是干一个什么事呢?来这样子,我先把代码拿过来,我做一个解释啊,同学们注意听讲。那现在我们讲一个高阶函数的第二个用法。
10:01
Hi。高阶。Order。Order function的第二个用法二吧。洗个来,朋友们,那现在呢,我们整一个这样的东西往这一放。我我这一方,我发现这代码写错了是吧,其实我一点错没有。这种错误一般是什么原因导致的呢?一般都是因为有特殊字符,最讨厌这个错误,这个代码我告诉你根本没错,你看啊。根据我的经验是没错的啊。你看这一写他才就对了,你知道为什么吗?这里面有偶尔你会发现你你粘贴的代码,诶有些东西说说老师我参加工作以后,我发现一个非常奇怪现象,我把别人代码拿过来一站利拷贝,人家那能运行,我这运行不了啊,我说你先看看有没有特殊字符。然后有些工具是可以看到特殊字符的,你知道吧,像那个A的plus,一打开里面有特殊字符一清,最好的方法就是。重写一遍啊,或者还有个方法,你看刚才我这个问题在这是不是直接我说一下这个技巧啊,因为将来你们肯定涉及到很多大量粘贴拷贝别人代码的问题,对吧,那是肯定的跑不了,你看我这直接拷贝过来,他是要报错的,因为这边肯定藏了隐隐藏字符了,那你最好的方法这样做,告诉大家你呢,对吧,有些同学也知道先写一个文本文件,你看把它打开。
11:25
打开过一放。往这一放呢,你先把它保存一下,其实这个地方它可以达到一个去格式化的目的啊,这个可以看到这个这个碱是不是本就透了。你看这是不是已经看出来这不是个减号了,看到没有。是吧,看起来好像是。这这这这是什么符号。干吗?一杠也太短了吧。我这个才是钢网。这是什么符号?这个是不是还不用输出来哦,这个。反正它不是减啊,所以说这个你一看就看出来,诶是这样子的问题,好这样子呢,你把它再保存,然后再把它粘贴过来,诶还有些还有一个小技巧,就是将来你们看不到特殊字符呢,有这个工具,很多工具都提示这样的功能,就是显示啊,它这有这样一个功能,显示所有的。
12:18
制表符。这样呢,也能看到一些问题,比如说有特殊字符的呢,它就看起来很怪。啊,这样呢,你你可以通过这个方式来来解决好一个小技巧,我们就分享到这,好站过来这就没错了,好现在呢,我们回头来说这个技技术,呃,这个问题啊,来大家讲一下,我说明一下这个东西。第一次我就多说两句,说明。第一个第一个首先首先这是一个这个函数呢,它返回的内容是这个。它接收值啊minusx y是一个高级函数。它是一个高阶函数,没问题,为什么说它是一个高阶函数呢?因为它返回了一个匿名函数。
13:04
因为它返回返回一个匿名函数,对匿名函数OK了,第二点我们来看它返回的匿名函数长什么德行呢?长这个德行,哎,这大家看现在大家就看懂了,因为我刚才刚刚讲完匿名函数,说这个它返回的匿名函数就这样子的返回的匿名。匿名函数是这个。啊,匿名函数是这个,而且大家有助于观察到啊,这个匿名函数还还很特别,它呢还用到了你这个min传进来的X。其实这个地方呢,有一个特殊的语法叫B包,但B包我待会再讲好,那么这个地方一一旦使用的话呢。好,你你如果调用的话呢,你就可以传一个值,它返回的是什么,返回就匿名函数,你可以用变量来接收。返回到匿名,匿名函数可以使用变量接收。
14:05
好,变量接受。那现在我们写完了,我们来测一下啊,啊,为了让大家看的清楚一点呢,我把这个分成两步写,这是一步写,我分成两步写,我分步执行。分布。分布啊。分步执行。好,第一步我先这样写,我先接收到一个一。好同学们,这个时候F1就是这个,你这个F1代表的就是它。但是准确的讲,F1代表是谁呢?准确的讲,这个F1代表的不是他,而是Y,这个应该这样写啊,此时此刻。F1就是什么呢?就是这个代码里面有个具体的值已经替换进去了。准确的讲,这个F1就是它就这个三已被填写填写进去了,而且只要你在这个F1的生命周期以内,这个三是固定不变的。
15:00
固定变的,每次调用它都是它,那么我们来看一下是不是这样道理,那朋友们我来演示一下啊,找一个。啊,PPNT f1给他传一个一大,就看我刚才讲了返回的是这个,那就三减一,因为你Y是Y是动态填进去的嘛,这个时候你调的是它哦。跟这个matters没关系了,你要看这段里面的代码,不要再看matters了,因为我说F1就是它。那你这个传进传进去的这个一是传到它这来了,那这个就是三减一等于二,我再来看一个,那么我再写一个。九注意这个九,你在调用的时候呢,它仍然调的是这种代码,这个三仍然没有动。只要你这个F1不死。它一直是三,那这样就相当于是三减九,那就等于负的六。啊OK,这样以此类推啊,大家要看懂,它是一旦这个返回这个三就固定的跟这个F1绑定在一起了,那我们执行一下。
16:04
运行这个结果,我们可以看到的确如此,对吧?二怎么是负六呢?啊,对的对的啊对,二负六,而且我们可以看出来F1的类型应该是方一。刚才已经讲这个东西了啊,这个类型也是有的,F1的类型刚才已经刚刚讲过,它的类型应该等于是方一,为什么是方一,因为它的形参是一个看效果。好,同学们可以看到它是方一,没毛病,大家要要很清醒认识到好。那么这种写法呢,有些人显得略微显得说不喜欢。那么这就出现了一个新的写法,其实就是函数颗粒化的写法,可以一步写完。也可以也可以一步到位,一步到位的调用,那这样也可以这样写,比如说有些同学老师minus,我传一个四,紧接着再传一个九。哎,这种写法呢,也是OK的,那这种写法呢,看起来好像很怪,其实你可以这样理解。
17:06
怎么理解这个东西呢?就相当于他先。执行了这个动作。这它显止你这种,那么相当于这地方就返回了一个匿名的函数,而且没有变量接收。那这个时候这个相当于说返回就是四减Y,那你又传了一个这个九,九就是Y,就是三减四减去九就应该等于负五。好,就这么来的啊,就是刚才刚才这句话就是写成写成一步就这样写的,那么就等于负五执行一下,跟我们想象的结果是完全一样的。正确。这个以后你们见的很多啊,这个你们将来看到这个代码,要立马就跟我们想Java一样,看的那么清,看得那么清晰。啊,但当然这个代码里面如果将来写的很复杂,很容易看蒙圈啊,很很容易看蒙圈,好,我把这一段关于我们写的这一个什么呢?就是关于这个高阶函数的这块内容先给大家反述一下,就是讲了一下高阶函数的呃,基本介绍和它的一些内容板述一下高阶函数。
18:13
要看懂啊。高阶函数的第一部分我们讲了啊,标题二说了一下高阶函数的基本介绍,对基本介绍和它的一个基本使用。高阶函数基本介绍,对,OK,那么函数高阶函数的基本使用,基本使用呢?这个案例我在这儿已经给大家准备好了,就是这个代码。哦,放过来啊,里面我写的很清楚。就是高阶函数的用法,那么紧接着呢,我们为了加深大家对它的认识,我们又说一下,高阶函数呢,它可以返回啊,可以返回函数类型,就是它不是返回一个普通类型,它返回的是函数类型,那么这段代码呢,就是刚才老师写的这段代码啊,可以一一步写,也可以分开写,可以分步执行,也可以一步到位的调用好,同学们要注意一下这个细节。
19:14
好的,那关于高级函数的前面部分,我们就先讲到这里。
我来说两句