- 高阶函数:接收另外一个函数为参数。可以用来创建减少代码重复的抽象控制结构。因为函数参数也表示的是一个算法。
-
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
的表达式传递给调用方。 - 传值参数则会在调用方执行函数体之间,计算参数的值,将其值传递给调用方。
- 传名参数并不会计算参数的值,直接将