目录
五、函数式编程
c、函数柯里化&闭包
-
闭包:如果一个函数,访问到了它的外部(局部)变量的值,那么这个函数和他所处的 环境,称为闭包 函数柯里化:把一个参数列表的多个参数,变成多个参数列表。 - 闭包案列
def main(args: Array[String]): Unit = { def f1()={ var a:Int = 10 def f2(b:Int)={ a + b } f2 _ } // 在调用时,f1 函数执行完毕后,局部变量 a 应该随着栈空间释放掉 val f = f1() // 但是在此处,变量 a 其实并没有释放,而是包含在了 f2 函数的内部,形 成了闭合的效果 println(f(3)) println(f1()(3)) // 函数柯里化,其实就是将复杂的参数逻辑变得简单化,函数柯里化一定存 在闭包 def f3()(b:Int)={ a + b } println(f3()(3)) }
d、递归
-
说明
一个函数/方法在函数/方法体内又调用了本身,我们称之为递归调用 - 案例练习
package chapter05 object dg { def main(args: Array[String]): Unit = { print(fact(5)) } //递归实现计算阶乘 def fact(n:Int) : Int = { def loop(n:Int,c:Int):Int = { if(n == 0) return c loop(n - 1,c * n) } loop(n,1) } }
f、控制抽象(传名参数)
案例练习:
package chapter05
object kzcx {
def main(args: Array[String]): Unit = {
// 1. 常规的传值参数
def f0(a:Int):Unit = {
println("a: "+ a)
println("a: "+ a)
}
f0(10)
def f1():Int = {
println("f1调用")
12
}
f0(f1())
println("=======================")
//传名参数,传递的不在是具体的值,而是代码块
def f2(a: =>Int):Unit = {
println("a: " + a)
println("a: " + a)
}
f2(23)
f2(f1())
f2({
println("这是一个代码块")
29
})
}
}
利用传名参数自定义while循环:
package chapter05
object zdywxh {
def main(args: Array[String]): Unit = {
var n = 10
//常规的while循环
while (n>=1){
println(n)
n -= 1
}
// 2.用闭包实现一个函数,将代码作为参数传入。递归调用
def tj(tj1: =>Boolean): (=>Unit) =>Unit ={
//内层函数需要递归调用,参数是循环体
def doLoop(op: =>Unit): Unit = {
if(tj1){
op
tj(tj1)(op)
}
}
doLoop _
}
n = 10
tj(n>=1)({
println(n)
n -= 1
})
// 3. 用匿名函数
def tj2(tj1: =>Boolean): (=>Unit) =>Unit ={
//内层函数需要递归调用,参数是循环体
op => {
if(tj1){
op
tj2(tj1)(op)
}
}
}
println("===================")
// 4. 柯里化实现
def tj3(tj1: =>Boolean)(op: =>Unit):Unit = {
if(tj1){
op
tj3(tj1)(op)
}
}
n = 10
tj3(n>=1)({
println(n)
n -= 1
})
}
}
g、惰性加载
- 说明
当函数返回值被声明为 lazy 时,函数的执行将被推迟,直到我们首次对此取值,该函 数才会执行。这种函数我们称之为惰性函数。 - 案例
package chapter05 object ljz { def main(args: Array[String]): Unit = { lazy val a:Int = sum(13,47) println("1.函数调用") println("2.a = "+a) println("4.a = "+a) def sum(i: Int, i1: Int):Int = { println("3.a调用") i + i1 } } }