一、概念

闭包:我们把一个函数与其相关引用环境(变量)组合成一个整体叫做闭包
概念晦涩难懂,下面我们用一个例子说明

二、小例子

def minusxy(x:Int) = (y:Int)=>x-y
val f=minusxy(20)
println("f(1)="+f(1))//19
println("f(2)="+f(2))//18

minusxy中x是匿名函数外部变量,但是却被用在匿名函数的里面,就像关在匿名函数里面一样,所以我们把一个函数与其相关引用环境(变量)组合成一个整体叫做闭包

解释:
1) (y: Int)=>x-y
返回的是一个匿名函数,因为该函数引用到到函数外的x,那么该函数和x整体形成一个闭包
如:这里val f= minusxy(20)的f函数就是闭包
2)你可以这样理解,返回函数是一个对象,而x就是该对象的一个字段,他们共同形成一个闭包
3)当多次调用f时(可以理解多次调用闭包),发现使用的是同一个x,所以ⅹ不变
4)在使用闭包时,主要搞清楚返回函数引用了函数外的哪些变量,因为他们会组合成一个整体(实体),形成一个闭包

相信你通过上面那个例子已经有所理解了,那么试试下面这个需求把

三、练练手

1)编写一个函数 makeSuffix(suffix: String)可以接收一个文件后缀名(比如.jpg),并返回一个闭包(closure)

2)调用闭包,可以传入一个文件名

如果该文件名没有指定的后缀(比如.jpg),则返回文件名.jpg。 文件名是 dog =》dog.jpg

如果已经有.jpg后缀,则返回原文件名。 文件名是cat.jpg => cat.jpg

3)要求使用闭包的方式完成

提示:String.endsWith(xx)
=========假装有条分割线=============

object ClosureDemo {

  def main(args: Array[String]): Unit = {
    val f=makeSuffix(".jpg")
    println(f("cat"))
    println(f("dog.jpg"))
  }

  /**
    * 闭包
    * @param suffix 变量
    * @return
    */
  def makeSuffix(suffix:String)=(fileName:String)=>{if (fileName.endsWith(suffix)) fileName else fileName+suffix}
}

四、闭包的好处

通过上边那个小练习我们知道,如果使用传统的方法,也可以轻松实现这个功能,但是传统方法需要每次都传入后缀名,比如.jpg,而闭包因为可以保留上次引用的某个值,所以我们传入一次就可以反复使用。