高阶函数
作为参数的函数
函数可以作为参数进行传递
def plus(a: Int) = a + 10
//Array(11, 12, 13)
Array(1, 2, 3).map(plus(_))
匿名函数
val array = Array(1, 2, 3)
//Array(11, 12, 13)
array.map((x: Int) => x + 10)
//Array(11, 12, 13)
array.map { (x: Int) => x + 10 }
高阶函数
能接受函数作为参数的函数叫做高阶函数;
个人理解:类似于回调函数
import scala.math._
def valueAtOneQuarter(f: (Double) => Double) = f(0.25)
valueAtOneQuarter(ceil _)
valueAtOneQuarter(sqrt _)
// 产出函数
def mulBy(factor : Double) = (x : Double) => factor * x
val quintuple = mulBy(5)
quintuple(20)
参数类型推断
def valueAtOneQuarter(f: (Double) => Double) = f(0.25)
// 传入函数表达式
valueAtOneQuarter((x: Double) => 3 * x)
// 参数推断省去类型信息
valueAtOneQuarter((x) => 3 * x)
// 单个参数可以省去括号
valueAtOneQuarter(x => 3 * x)
// 如果变量旨在=>右边只出现一次,可以用_来代替
valueAtOneQuarter(3 * _)
val fun2 = 3 * (_: Double) // OK
val fun3: (Double) => Double = 3 * _ // OK
闭包
闭包就是一个而函数吧外部的那些补数据自己的对象也包含进来了
闭包机制使用起来就像是一个函数样板
def mulBy(factor : Double) = (x : Double) => factor * x
val triple = mulBy(3)
val half = mulBy(0.5)
println(triple(14) + " " + half(14))
mulBy相当于是两个函数嵌套。
- 匿名函数
(x:Double)=> factor * x
嵌套在函数mulBy中 - 匿名函数使用了外部变量、mulBy的局部变量factor而不是全局变量
- 函数mulBy返回了引用局部变量的匿名函数
triple、half这两个函数就叫闭包,闭包有代码和代码用到的任何非局部变量定义构成
有权访问另一个函数作用域内变量
柯里化
函数编程中,接受多个参数的函数都可以转为接受单个参数的函数,这个转化过程就叫柯里化,柯里化就是证明了函数只需要一个参数而已。
// 传统定义两个参数
def mul(x:Int, y: Int) = x * y
mul(6,7)
// 柯里化定义,使用到了闭包
def mulOneAtATime(x: Int) = (y: Int) => x * y
mulOneAtATime(6)(7)
// Scala中可以简写
def mulOneAtATime(x: Int)(y: Int) = x * y
val a = Array("Hello", "World")
val b = Array("hello", "world")
// def corresponds[B](that: GenSeq[B])(p: (A,B) => Boolean): Boolean
a.corresponds(b)(_.equalsIgnoreCase(_))
控制抽象
控制抽象是一类函数
特点:
- 参数是函数
- 函数参数没有输入值也没有返回值
def runInThread(block: () => Unit) {
new Thread {
override def run() {
block()
}
}.start()
}
// 传入函数
runInThread { () => println("Hi"); Thread.sleep(10000); println("Bye") }
// 这种叫控制抽象 函数
def runInThread(block: => Unit) {
new Thread {
override def run() {
block
}
}.start()
}
// 优雅的传入
runInThread {
println("Hi");
Thread.sleep(1000);
println("Bye")
}
// 定义类while的until方法,
def until(condition: => Boolean)(block: => Unit) {
if (!condition) {
block
until(condition)(block)
}
}
var x = 10
until(x == 0) {
x -= 1
println(x)
}
Thread.sleep(10000)