高阶函数的介绍和使用 | 学习笔记

简介: 快速学习高阶函数的介绍和使用

开发者学堂课程【Scala 核心编程 - 进阶高阶函数的介绍和使用学习笔记,与课程紧密连接,让用户快速学习知识。

课程地址https://developer.aliyun.com/learning/course/610/detail/9091


高阶函数的介绍和使用


内容介绍:

一、匿名函数

二、高阶函数基本介绍

三、高阶函数基本使用

四、运行高阶函数

五、高阶函数可以返回函数的类型


一、匿名函数

请编写一个匿名函数,可以返回2个整数的和,并输出该匿名函数的类型.

//下面的f1就可以是一个匿名函数,调用的时候通过匿名函数传参就可以了,如果不传参数就代表输出这个类型,传上参数就代表调用这个匿名函数。

val f1 = (n1: lnt,n2: Int ) => {

println("匿名函数被调用")

n1 +n2

}

println("f1类型=”+ f1)

println(f1(10,30))

传上参数代表调用匿名函数,不传参数就代表输出类型。


二、高阶函数基本介绍

高阶函数除了可以接受一个函数之外,他还可以返回一个函数,这是他很重要的特色。高阶函数能够接受函数作为参数的函数,叫做高阶函数(higher-order function)。

可使应用程序更加健壮。高阶函数可以接收一个函数也可以返回一个函数。


三、高阶函数基本使用

//test 就是一个高阶函数,它可以接收 f: Double =>

Double

Def  test(f: Double => Double, n1: Double)= {

f(n1)  (这里的test函数可以接收一个高阶函数,这个函数的类型是传入double返回double要匹配,后面传入一个普通的参数,在里面调用一个传入的函数并去执行它。)

}

//sum是接收一个Double,返回一个Double

def sum(d: Double): Double ={

d + d

}

sum 函数接受一个打包返回一个 double 的案例,调用的时候很简单,就是test,把sum 函数传进去,再把6.0传进去,6.0传入到了n1,这个n1又传入到了传入的函数去执行,逻辑是很清晰的。

val res = test(sum, 6.0)//6.0传入n1

println("res=" + res)


四、运行高阶函数

创建新的 Scala Class,name 为 HigherOrderFunction,Kind 为 Object。

把6.0传给 sum,在底层 text 里面调,sum 将地址传给f1。f指向了Sum的地址,大致的逻辑是6.0传给了 n1,传完之后 sum 是有地址的,Sum 将地址传给f1,到了执行test的时候,因为f1的地址指向了sum,所以会到 sum 这边来执行,N1会被传入到f(n1),执行结束以后,把结果返回给test.

object HigherorderFunction {

def main(args : Array[string]): unit = {

def test(f: Double => Double,n1: Double) = {

f(n1)

}

// sum是接收一个Double,返回一个Double

def sum( d: Double): Double ={

d + d

}

val res = test( sum,6.0)

//println( "res=" +res) // 结果为12.0

object HigherorderFunction {

def main( args : Array [string]): unit = {

def test(f: Double => Double,f2: Double =>Int , n1: Double) = {

f(f2(n1)) //f(0)

}

//sum是接收一个Double,返回一个Double

Def sum(d: Double): Double = {

d + d

}

问题:高阶函数里面能不能再调用一个函数?

在此处做一个扩展,如果对f1做一个取模的操作,取模过后再传给f,那么这个过程可不可以呢?

通过以下过程进行验证

Def函数用来把double转成int再返回取模的值,假如写成以下函数,同时改写上面代码为 def test(f: Double => Double,f2: double  =>Int,n1:Double)= {   f2传进来是一个 double 类型,double 类型返回的是 int 类型。

先把 f1传给 f2,把n1再传进去,即f(f2(n1)),下方再传入一个 mod,所以在这个地方不能认为只能传入一个高阶函数,而是可以传入多个函数,函数之间也可以进行调用,这样功能就会更加倍拓展,比如在高阶函数里面使用集合的map、reduce等等,如果以后再用的时候用到匿名函数,可能传入的不是一个函数,可能会传入多个函数。

def mod(d: Double): Int = {

d.toInt %2

}

val res = test(sum,mod,6.o)//

println( "res=" +res) // 0.0

}

}

首先把6.0传给了f2,f2是mod,mod把6.0先取整在模2,应该等于0,只要结果是0.0,那就说明代码是正确的

运行结果如下:

Res=0.0

Process finished with exit code 0


五、高阶函数可以返回函数的类型

函数的闭包就是由高阶函数可以返回函数的类型引起的。高阶函数不仅可以接受一个函数,也可以返回一个函数,返回还可以继续执行。

代码放进去显示错误,但是实际上是没有错误的,这种错误一般是由于特殊字符导致的,有的时候拷贝过来之后发现会出现错误,那就首先要看有没有特殊字符最好的方法就是重新输入一遍。

或者是在桌面新建一个文本文件,打开后把复制的代码放入新建的文本文件,可以打到一个去格式化的目的,保存然后再进行复制粘贴即可除此之外,还有一个小技巧,在文本文件里面打开视图,选择空白,点击全部,可以看到所有的制表符

新建新的Scala Class,name为HigherOrderfuncton2,Kind为Object。

object HigherorderFunction2 {

def main( args : Array[string]) : unit = {

def minusxy(x: Int) = {

(y: Int) => x-y//匿名函数}

val result3 = minusxy(3)(5)

println( result3)

//说明

//1. minusxy 是高阶函数,因为它返回匿名函数

//2.返回的匿名函数(y: Int) =>X-y,它还用到了minusxy传进来的x,这个地方有一个特殊语法叫闭包。

// 3.返回的匿名函数可以使用变量接收

def minusxy(x: Int)= {

(y: Int)=> x-y//匿名函数  

}

//分步执行

//f1就是(y,int)=>3-y,3是固定不变的,每次调用都是3

val result3 = minusxy(3)

println(""f1的类型“ + f1)

println(f1(1))//2(y是动态填进去的,调用的是(y,int),和minusxy没有关系了,看里面的代码)

运行结果为:

res=2.0

println(f1(9))//-6(9在调用的时候仍然是用的(y,int)=>3-y

运行结果为:res=-6

f1的类型是Function1,因为它的形参是一个。

//也可以一步到位的调用

printLn(minusxy(4)(9))// -5

先执行minusxy(4),相当于返回了一个匿名函数,而且没有变量接收,相当于是4-y,因为后面又传入了一个9,9就是y,就变成了4-9,结果就是-5.

相关文章
|
存储 安全 Java
【面试题精讲】ArrayList 和 Vector 的区别?
【面试题精讲】ArrayList 和 Vector 的区别?
|
人工智能 数据库 Docker
探索人工智能的世界:构建智能问答系统之环境篇
【6月更文挑战第7天】在本教程中,作者指导读者如何搭建项目环境,包括安装Python 3.10、Docker Desktop和Visual Studio Code。安装Python时可按默认设置进行,Docker Desktop用于管理数据库容器,提供更好的开发和测试环境。Visual Studio Code是一个推荐的源代码编辑器。虽然尝试使用cursor开发时遇到问题,但最终选择了使用VS Code。但建议本地开发。配置文件部分,提供了`docker-compose.yaml`、`Dockerfile`和`pyproject.toml`的示例,用于构建和管理项目容器。
206 5
探索人工智能的世界:构建智能问答系统之环境篇
|
前端开发 容器
揭秘Web前端布局秘籍:浮动,那个让你又爱又恨的布局神器,你真的了解它吗?
【8月更文挑战第23天】在Web前端设计中,浮动是一种关键布局技术,能让元素在文档流中灵活移动,实现文本环绕图片、多列布局等效果。元素通过CSS的 `float` 属性脱离正常文档流并移动到容器边缘,后续非浮动内容则围绕该元素排列。浮动可用于多列布局、导航菜单及图文混排。需注意清除浮动以避免布局问题,并处理可能导致的父元素高度塌陷。
302 0
leetcode-537:复数乘法
leetcode-537:复数乘法
135 0
|
Web App开发 存储 移动开发
我的前端成长之路:在阿里七年,我的成长和迷茫
很荣幸有这个机会和大家分享一下我的成长经历,以及我是如何摆脱业务前端的职业迷茫感的。
我的前端成长之路:在阿里七年,我的成长和迷茫
|
算法 C++ Python
昨晚学妹参加了B站秋招笔试,还想考考我?
昨晚学妹参加了B站秋招笔试,还想考考我?
178 0
|
SQL 监控 安全
发卡系统代码审计
发卡系统代码审计
|
Windows
Windows、Word、常用快捷键
Windows、Word、常用快捷键
220 0
|
Oracle Java 关系型数据库
正常性入职岗前培训(非培训机构的实习生入职培训)---基础知识总结
一:正常性大三实习生入职岗前培训总结: 也许题目应该叫"那个矫情的大三实习生已经入职实习了": 之前那个矫情的大三生写的找工作的感受(上次是偏理论性,这次是实践性出来找工作): 一个忙着找实习工作的大三在校生的真实感受:http://www.cnblogs.com/biehongli/p/6831510.html 1:先说说如何找工作的吧,希望对大三的(非考研的,非靠公务员,想从事本行业的),想出去找工作的有所帮助,我在河南南阳就读,地处偏远,离大城市偏远。
2078 0