Scala 基础(十二):Scala 函数式编程(四)高级(二)参数(类型)推断、闭包(closure)、函数柯里化(curry)、控制抽象

1  参数(类型)推断

参数推断省去类型信息(在某些情况下[需要有应用场景],参数类型是可以推断出来的,如list=(1,2,3) list.map() map中函数参数类型是可以推断的),同时也可以进行相应的简写

参数类型推断写法说明

1)参数类型是可以推断时,可以省略参数类型

2)当传入的函数,只有单个参数时,可以省去括号

3)如果变量只在=>右边只出现一次,可以用_来代替

应用案例

//分别说明
val list = List(1, 2, 3, 4)
println(list.map((x:Int)=>x + 1)) //(2,3,4,5)
println(list.map((x)=>x + 1))
println(list.map(x=>x + 1))
println(list.map(_ + 1))
val res = list.reduce(_+_)

应用案例的小结

1)map是一个高阶函数,因此也可以直接传入一个匿名函数,完成map

2)当遍历list时,参数类型是可以推断出来的,可以省略数据类型Int println(list.map((x)=>x + 1))

3)当传入的函数,只有单个参数时,可以省去括号 println(list.map(x=>x + 1))

4)如果变量只在=>右边只出现一次,可以用_来代替 println(list.map(_ + 1))

2  闭包(closure)

基本介绍:闭包就是一个函数和与其相关的引用环境组合的一个整体(实体)。

//1.用等价理解方式改写 2.对象属性理解
def minusxy(x: Int) = (y: Int) => x - y
//f函数就是闭包.
val f = minusxy(20) 
println("f(1)=" + f(1)) // 19
println("f(2)=" + f(2)) // 18

1)第1点 (y: Int) => x – y

返回的是一个匿名函数 ,因为该函数引用到到函数外的 x,那么 该函数和x整体形成一个闭包

如:这里 val f = minusxy(20) 的f函数就是闭包

2)你可以这样理解,返回函数是一个对象,而x就是该对象的一个字段,他们共同形成一个闭包

3)当多次调用f时(可以理解多次调用闭包),发现使用的是同一个x, 所以x不变。

4)在使用闭包时,主要搞清楚返回函数引用了函数外的哪些变量,因为他们会组合成一个整体(实体),形成一个闭包

闭包的好处

1)返回的匿名函数和 makeSuffix (suffix string) 的 suffix 变量 组合成一个闭包,因为 返回的函数引用到suffix这个变量

2)我们体会一下闭包的好处,如果使用传统的方法,也可以轻松实现这个功能,但是传统方法需要每次都传入 后缀名,比如 .jpg ,而闭包因为可以保留上次引用的某个值,所以我们传入一次就可以反复使用。大家可以仔细的体会一把!

3  函数柯里化(curry)

1)函数编程中,接受多个参数的函数都可以转化为接受单个参数的函数,这个转化过程就叫柯里化

2)柯里化就是证明了函数只需要一个参数而已。其实我们刚才的学习过程中,已经涉及到了柯里化操作。

3)不用设立柯里化存在的意义这样的命题。柯里化就是以函数为主体这种思想发展的必然产生的结果。(即:柯里化是面向函数思想的必然产生结果)

函数柯里化快速入门

编写一个函数,接收两个整数,可以返回两个数的乘积,要求:

使用常规的方式完成 使用闭包的方式完成 使用函数柯里化完成

//说明
def mul(x: Int, y: Int) = x * y
println(mul(10, 10))

def mulCurry(x: Int) = (y: Int) => x * y
println(mulCurry(10)(9))

def mulCurry2(x: Int)(y:Int) = x * y
println(mulCurry2(10)(8))

4 控制抽象

如何实现将一段代码(从形式上看),作为参数传递给高阶函数,在高阶函数内部执行这段代码. 其使用的形式如 breakable{} 。

var n = 10
breakable {
while (n <= 20) {
n += 1
if (n == 18) {
  break()
}
}
}

控制抽象基本介绍

控制抽象是这样的函数,满足如下条件

1)参数是函数

2)函数参数没有输入值也没有返回值

def myRunInThread(f1: () => Unit) = {
      new Thread {
        override def run(): Unit = {
          f1()
        }
      }.start()
    }
    myRunInThread {
      () => println("干活咯!5秒完成...")
        Thread.sleep(5000)
        println("干完咯!")
    }

简化处理,省略(),如下形式

进阶用法:实现类似while的until函数

原文地址:https://www.cnblogs.com/qiu-hua/p/13260300.html