开发者学堂课程【Scala 核心编程 - 进阶:闭包】学习笔记,与课程紧密连接,让用户快速学习知识。
课程地址:https://developer.aliyun.com/learning/course/610/detail/9093
闭包
内容介绍:
一、基本介绍
二、案例演示
三、代码小结
四、闭包的最佳实践
五、代码演示
六、闭包的好处
前端开发人员水平的高低取决于 JavaScript,所有框架的底层都是由js写的,Js是前端人员的核心,做前端开发的人 js 水平的高低直接决定薪水的高低,就像学大数据的应用能力和算法。
一、基本介绍
几乎在所有语言里都会出现闭包的概念,闭包是一种语法的现象,不是某一个语言单有的,闭包的专业术语是 closure。
基本介绍:
闭包(closure)就是一个函数和与其相关的引用环境组合的一个整体(实体)。
函数用到了函数以外的变量,而这个变量和函数,形成了一个整体,有点类似于对象实例和对象,在很多语言里面,闭包的本质就是对象。
二、案例演示
//1.用等价理解方式改写2.对象属性理解
def minusxy(x: lnt) = (y: Int)=>x -y
//f函数就是闭包.
val f = minusxy(20) (y: Int)=>x -y是一个函数,函数里面用了一个变量x,x并不是它的,而是从x外部传进来的,所以可以认为(y: Int)=>x -y这个匿名函数加上外部变量x构成了一个闭包,外部变量x跟随(y: Int)=>x -y进行变化,(y: Int)=>x -y将x进行闭合了。
printin("f(1)=”+f(1))
//结果为19
println("f(2)=”+ f(2))
//结果为18
有些语言里面x是变量,可以在内部进行递增,但是在val里面x传进来之后改不了,如果写成(++x)是错误的,第一因为语言不支持,第二个即使语言支持,在VAL里面也动不了它。
三、代码小结
1)第1点
(y: Int)=> x-y
返回的是一个匿名函数,因为该函数引用到到函数外的x,那么该函数和x整体形成一个闭包
如:
2)这里val f = minusxy(20)的f函数就是闭包,函数的本质是一个对象。
返回函数是一个对象,而x就是该对象的一个字段,它们共同形成一个闭包
3)当多次调用f时(可以理解多次调用闭包),发现使用的是同一个x,所以x不变。
4)在使用闭包时,主要搞清楚返回函数引用了函数外的哪些变量,因为它们会组合成一个整体(实体),形成一个闭包。
想要弄明白闭包就要分析出两大部分,第一,到底是哪个函数。第二,函数到底运用了哪些变量。那就意味着,闭包可能是闭合的一个变量,也有可能是多个变量。
四、闭包的最佳实践
新建一个 Scala class,Kind为Object。
请编写一个程序,具体要求如下
1)编写一个函数makeSuffix(suffix: String)可以接收一个文件后缀名(比如.jpg),并返回一个闭包
2)调用闭包,可以传入一个文件名,如果该文件名没有指定的后缀(比如.jpg) ,则返回文件名.jpg,如果已经有.jpg后缀,则返回原文件名。
比如文件名是dog=>dog.jpg
比如文件名是cat.jpg => cat.jpg(相当于是补齐后缀,在第一次产生闭包的时候就填进去了)
3)要求使用闭包的方式完成
4) String.endsWith(xx)
五、代码演示
//使用并测试
val f = makesuffix(".jpg")
println(f( "dog-jpg" )) /
/
dog .jpg
println(f( "cat")) //cat.jpg如果没有后缀,它会自动补齐后缀并返回,只要传入一次后缀名,后面就不用再重复操作。如果用普通的函数来做,因为普通的函数式不保留变量的,所以每次都要传一个参数。
}
def makesuffix(suffix: string) = {
//返回一个匿名函数,会使用到 suffix
因为返回的是闭包,所以不要写 unit。首先要写上形参,因为会使用到文件名,文件名的类型是string,代码比较多,所以运用大括号,如果名字有suffix这个后缀,就直接返回文件名,如果没有就需要加上后缀。
(filename : string) =>{
if (filename.endswith( suffix)) {
filename
}else {
filename + suffix
}
}
}
}
六、闭包的好处
1)返回的匿名函数和 makeSuffix (suffix string)的 suffix 变量组合成一个闭包,因为返回的函数引用到 suffix 这个变量
2)体会一下闭包的好处,如果使用传统的方法,也可以轻松实现这个功能,但是传统方法需要每次都传入后缀名,比如.jpg ,而闭包因为可以保留上次引用的某个值,所以传入一次就可以反复使用,说到本质上就类似于对象、属性和方法的关系。