00:00
我们已经了解了SC中函数的一些基本的概念和用法。以及函数质简原则,怎么样去做化简,能省则省,在这基础上呢?我们又引出了所谓的匿名函数拉姆达表达式。当然大家也发现啊,匿名函数其实并不简简单单的,只是为了让函数更加的简化,它其实可以实现更多更复杂的功能,所以这其实已经属于函数的高级应用了。啊,那我们接下来就在总结或者概括一下函数的一些高阶应用,要高阶函数有哪些使用的方式,那我们还是回顾一下啊,我们说在skyla这样一门函数式编程语言里边。函数其实是一等公名,那就是它地位很高,这是怎么样体现出来的呢?啊,那一方面就是我们在代码的任何地方,直接去把一个代码块啊,直接的提炼出来,我们就可以去声明定义一个函数,它非常的灵活,不像Java里边啊,我们只能把它声明成对象的方法,在类里边去做一个定义,在盖拉里边非常的灵活,这是一方面。那另外一方面呢,就是函数它作为一个表达式,作为一个表达式的值可以有更加高阶的用法,那这主要是体现在三个方面,前面我们讲到匿名函数的时候,其实已经有所体现啊,就一个是函数可以作为值进行传递。
01:30
另外呢,函数可以作为参数进行传递,也就是说有些函数可以,它的参数本身又是一个函数啊,这是第二种用法,那最后还有一种就是函数还可以作为函数的返回值返回,哎,什么意思呢?就是一个函数,它的参数可以里边有有函数,它的返回值也可以是一个函数啊,这就具体来讲就会有非常复杂的一些高级的应用了,我们还是在代码里边来做一个简单的测试。
02:02
还是在第五章的包下边,我们去新建一个Java,呃,Skyla的object,那接下来我们测试就是test,零六要测的是一些一些高阶的用法啊,所以我们写I order function那方法写出来,那首先我们还是先正常的定义一个函数吧,F定一个F啊,那现在我们把这个分数和返回值的类型稍微的改一下,我们定一个int类型吧,传入一个N返回,呃,还是返回一个int里边的逻辑的话,我们就写的简单一点,Print line1句,这个是fu。那我们知道最终它是要返回一个int类型的值的,那比方说我们就直接返回N加一吧,啊,这个非常简单的一种实现啊,那如果要是调用的话,我们可以一个result接收当前F调用的返回值,比方说F传入一个123啊,那大家知道这个result值肯定就是int了,先复用之后。
03:14
得到的返回值就是int类型嘛,所以这个result是int类型,我们可以把这个result做一个打印输出运行一下啊,那这个其实非常简单,我们可以看到F123,这就肯定调用了一次F嘛,所以有一个F调用,那得到的值是什么呢?N加一,那显然是124了,所以result就是124,这是最简单的一个函数声明和调用的过程,然后接下来呢,我们就要看一些高级的用法,不接的用法了,那第一种用法就是函数可以作为值进行传递,那作为值进行传递,当然就是把一个函数要直接赋给另外一个变量了,前面我们讲到匿名函数的时候有过这样的定义啊,那大家想到,那就相当于是给匿名函数又定义了一个名称嘛,而我们现在呢,哎,我们现在其实是相当于可以把这个一般的函数,这里的F,这不是匿名函数,它。
04:14
这个一般的函数同样也可以作为一个值传给另外一个变量,有点像就是把这个函数好像是重命名一下的感觉啊,所以呃,在有些场景下啊,还是需要做这样的一个转换的,那比方说这里边我们定义一个F1。大家看这个函数作为直径传递,那怎么办呢?是直接这样呃。给小括号,然后里边再传一个直径来吗?那肯定不能这样,这样的话,这相当于是一个函数调用,函数调用之后返回的当然就是一个它调用的int这个结果了,我们这里要的F1是直接接收F这个函数,而不是要接收一个调用之后的int类型的值,所以这里边呢,我们就直接把F放在这里,大家看里边你直接把F放在这里,它直接报错对吧?我们这里如果直接运行的话,它同样会告诉我们有这样的一个问题,那他要求我们怎么样去写呢?
05:15
哎,大家看到就是我们要表示F是一个函数整体的时候,你可以用这种方式写在F后边空一格加一个下划线。那就表示F,我们使用的时候,它是一个整体。它是要表示F本身函这个函数啊,那当然大家就知道了,F本身这个函数对于F1而言啊,我们如果要是写出它的类型的话,应该是什么类型呢?哎,当然就是是它的。参数输入参数类型,然后返回值类型还是int,所以大家看如果写这个对应的函数类型的话,那就那个之前拉姆达表达式一样啊,直接写成这样一个箭头的形式,前边是参数类型,后边是返回值的类型,所以F1就是这样的一个变量了。
06:08
啊呃,那其实这里面大家会发现把这个写出来之后,后边反而这里边有一个爆黄的这样一个warning的提示,那是什么意思呢?其实是说如果前面我们已经指定了F1就是这样的一个函数类型的话,那其实大家会发现这个编译器就不会搞错了,对吧,我后面直接其实就不需要再加这个下划线了。我直接就把F放在这儿,已经知道是要把这个完整的函数传递给F1,因为F1的它的值就是一个函数啊啊,所以这是有两种写法的啊,我们可以单独的给大家写出来,F1是这样去写,F2我们定义的时候,如果省略它本身的这个函数类型的话,我们可以在后边空格加一个下划线,明确的告诉编译器,F2要的是函F这个函数体,我们要的就是这个函数啊,这样的话就可以直接去使用了啊,当然如果直接使用的过程当中print line啊,大家可能会想到我如果直接打印这个F1,那会是一个什么结果呢?
07:14
这个可以大家可以想象一下啊,然后当然了,具体来测的时候,F1本身这个函数嘛,里边可以传一个分数进去,对吧?啊,那与之对应的。来F2,我们同样也可以把这个F二传传一个参数进去。大家可以看一下运行的结果是什么样,那肯定不会报错了,大家可以看到,呃,这里边首先。我们传这个F1,传进来的时候,Print line f1,大家看打印出来的是是一串引用对吧?哎,所以这里边其实这里边给的是一个什么呢?大家看这是一个拉姆达,所以这里边其实本身是一个函数的引用地址,那为什么这里边函数又会有一个引用地址呢?这就又涉及到SKY的底层呢,它既是一个函数式编程的语言,又是一个完全面对对象的语言,在它的底层啊,不管是拉姆达表达式匿名函数,还是我们这里边定义好声明出来的这个函数,它其实如果说我们要比方说啊,拿到一个函数的值赋给一个变量的话,那这个变量其实都是一个。
08:30
是一个function的象,也就是说它都是一个函数对象,本质上还是面对对象的,所以在这里大家就知道了,你要单独去看这个F1和F f2的话,他们的对象引用肯定都是不一样啊,所以这里边我们看到的是两个不同的引用,然后接下来如果要调用的话,这就一样了,对吧?这里F一传一个12进去,那么F被调用得到的是十三普line打印出来是13加一的结果,那同样F2调传进去之后也是F被调用,然后打印出来的是36 35加一的结果。
09:07
这就是把函数作为值进行传递的结果啊,那当然了,前面我们这里边举的例子是它本身有参数也有返回值,那假如说我们在定义另外一个函数TFB,比方说没有参数,这种情况下又怎么办呢?啊,比方说这里我们把这个直接返回到这里。比方说这里我们直接返回一了啊,因为没有对应的参数传进来嘛,这里是f fun调用,那大家就会想到了,后边我如果要去处理的时候直接调用的话,其实这里我是可以大家会想到这里调用的时候,是不是直接就是一个fun就可以了呀,Fun也就可以直接调用,甚至前面我们还讲到了啊,整略括号是不是也算是一种调用的方式啊,啊这种写法都是对的,那接下来如果我们要想表示,比方说我们在定义一个F3。
10:06
想表示这个f fun本身这个函数体的话,那应该怎么样呢?这这个大家要注意啊,肯定我这里边不能直接给这个f fun,因为如果给这个的话,这就是相当于一次一次调用吧啊,那所以完整的写出来定就应该是fun空格在啊下划线这样的话表示的就是当前用的这个函数体啊,所以接下来如我们把这个做一个啊硬输出F4。这就会看的很明显,F3本身这是一,这是f fun调用一次的那个返回值一,而F4呢,它本身是一个函数啊,那当然了,如果这里大家能把F3的类型直接写出来的话,是它也就是一个函数了,就是如果你明确的指定是函数,就像我们这里啊,明确的指定了这个返回返回返回,呃,这个当前这个变量的类型是函数类型,那你后边的话,即使有。
11:09
这直接后面什么都不加,它也不会有歧义,哎,我这里边就直接知道它是一个函数了,所以这里面它的类型应该是什么呢?注意是空参数,空参数的话括号不能省啊,所以是一个空括号,然后返回一个英特练习,这样写的话也是对的,那接下来大家如果看的话,你就会看到得到的是两个引用,F3和F4就都是函数了。啊,这就是关于函数作为值进行传递的一些测试。
我来说两句