Chapter 09 《Control Abstraction》

    1. 高阶函数:接收另外一个函数为参数。可以用来创建减少代码重复的抽象控制结构。因为函数参数也表示的是一个算法。
    1. currying,可以用来辅助构建新的抽象控制,感觉就像是内建的一样。一个经过currying的函数支持多个函数列表。调用的过程中,如果没有入参到最后一个参数列表,那么交出的都是函数。也就是函数类的函数值,这里的函数值并不是一个数值,而是函数类的一个实例对象。
scala> def curriedSum(x: Int)(y: Int) = x + y
curriedSum: (x: Int)(y: Int)Int

获取到中间函数的做法,使用部分应用函数,传入部分参数:

curriedSum(1) _  //交出第二个函数的引用。

在这个过程中val a = curriedSum(1)_, a(4)的时候编译器可以让1存活在堆上,从而计算得到1+4=5


实现新的控制结构
  • 对常见的编码模式进行抽象。
def withPrintWriter(file: File, op: PrintWriter => Unit) = {
val writer = new PrintWriter(file)
try {
op(writer)
} finally {
writer.close()
}
}
  • 该模式被称为loan pattern,因为是将资源打开并贷出给op,而且最后关闭资源的也是该控制结构,和用户并没有关系。
  • 可以使用{}而不是()使得调用方的代码更像是在使用内建的控制结构。当函数的参数只有一个的时候,可以使用{}。目的是在{}中书写函数字面量,用起来更像是抽象控制。使用currying{}可以使得创建的控制结构更像是内建的。
def withPrintWriter(file: File)(op: PrintWriter => Unit) = {
val writer = new PrintWriter(file)
try {
op(writer)
} finally {
writer.close()
}
}

val file = new File("date.txt")
withPrintWriter(file) { writer =>
writer.println(new java.util.Date)
}

或者在currying的函数中,只有最后一个参数列表可以使用{}


传名参数
  • 参数语法(num: => Int)
    • 传名参数并不会计算参数的值,直接将num的表达式传递给调用方。
    • 传值参数则会在调用方执行函数体之间,计算参数的值,将其值传递给调用方。

你可能感兴趣的:(Chapter 09 《Control Abstraction》)