Scala 高阶函数
一、函数作为参数
highOrderFunc是一个高阶函数,因为它可以接收一个函数作为参数
object PartialFunctionDemo {
def main(args: Array[String]): Unit = {
val add = (d: Double) => d + 1
val res = highOrderFunc(add, 5)
println(res)
}
def highOrderFunc(f: Double => Double, p: Double) = f(p)
}
二、函数作为返回值
函数f接收一个参数n,返回一个函数(x: Double) => n - x
f(5)(8),f(5)的返回值是一个函数,(8)是上一步返回函数的参数
def main(args: Array[String]): Unit = {
val f = (n: Double) => (x: Double) => n - x
val res = f(5)(8)
println(res) // -3
}
三、闭包 closure
闭包就是一个函数和与其相关的引用环境组合的一个整体。如下代码中mkSuffix函数的返回值就是一个函数,这个函数引用到了外部的suffix,它们共同组成一个闭包。好处是变量suffix一次传入,后面可以多次使用。
def main(args: Array[String]): Unit = {
val suffix = mkSuffix(".jpg")
println(suffix("cat")) // cat.jpg
println(suffix("dog.jpg")) // dog.jpg
}
def mkSuffix(suffix: String) = {
(fileName: String) => if (fileName.endsWith(suffix)) fileName else fileName + suffix
}
四、函数科里化
如下代码,求1到5的乘积。函数科里化可以将需要多步完成的一个函数,拆解成每步完成一件事的多个函数。这样做的好处是拆解出更加细粒度的函数,得到共用的中间结果,类似于代码封装、数仓分层的思想。
object PartialFunctionDemo {
def main(args: Array[String]): Unit = {
val res1 = curry01(1)(2)(3)(4)(5)
println(res1) // 120
val temp = curry2(1)(2)(3)
val res2 = temp(4)(5)
println(temp) // <function1>
println(res2) // 120
}
def curry01(a: Int)(b: Int)(c: Int)(d: Int)(e: Int) = a * curry02(b)(c)(d)(e)
def curry02(b: Int)(c: Int)(d: Int)(e: Int) = b * curry03(c)(d)(e)
def curry03(c: Int)(d: Int)(e: Int) = c * curry04(d)(e)
def curry04(d: Int)(e: Int) = d * curry05(e)
def curry05(e: Int) = e
def curry2(a: Int) = {
b: Int => c: Int => d: Int => e: Int => a * b * c * d * e
}
}
五、控制抽象
函数test的参数是一个函数f,而且函数f既没有输入值也没有返回值,此时函数test就叫控制抽象
object ScalaDemo {
def main(args: Array[String]): Unit = {
test(f _)
}
def test(f: () => Unit) = {
f()
}
def f = {
println("hello")
println("scala")
}
}
对于控制抽象函数,可以作如下简写
object ScalaDemo {
def main(args: Array[String]): Unit = {
//传递参数函数f时,直接传递代码块。如果只有一行,可以用小括号
test{
println("hello")
println("scala")
}
}
//去掉入参的小括号,: 和 => 之间有空格
def test(f: => Unit) = {
//调用时也去掉小括号
f
}
}
利用控制抽象,实现一段循环
object ScalaDemo {
def main(args: Array[String]): Unit = {
var num = 10
until(num > 0) {
num -= 1
println(num)
}
}
def until(condition: => Boolean)(block: => Unit): Unit = {
if (condition) {
block
//递归调用
until(condition)(block)
}
}
}

浙公网安备 33010602011771号