Scala系列之:函数高级
- 一、匿名函数
- 二、函数高级用法
- 三、函数高级应用案例
- 四、函数柯里化和闭包
- 五、传值参数和传名参数
- 六、惰性加载
一、匿名函数
- 没有名字的函数就是匿名函数
(x:Int)=>{函数体}
- x:表示输入参数类型
- Int:表示输入参数类型
- 函数体:表示具体代码逻辑
匿名函数的至简原则
object LambdaTest {
def main(args: Array[String]): Unit = {
val fun = (name: String) => {println(name)}
fun("篮球")
//匿名函数作为参数
def f(func: String => Unit): Unit = {
func("足球")
}
f(fun)
println("--------")
f((name: String) => {println(name)})
}
}
匿名函数的至简原则
- 参数的类型可以省略,会根据形参进行自动推导
- 类型省略后,发现只有一个参数,则圆括号可以省略。其他情况,没有参数和参数超过1的永远不能省略圆括号。
- 匿名函数如果只有一行,则大括号也可以省略
- 如果参数只出现一次,则参数省略且后面参数可以用_代替。
- 如果可以推断出,当前传入的println是一个函数体,而不是调用语句,可以直接省略下划线
object LambdaTest {
def main(args: Array[String]): Unit = {
val fun = (name: String) => {println(name)}
fun("篮球")
//匿名函数作为参数
def f(func: String => Unit): Unit = {
func("足球")
}
f(fun)
println("--------")
f((name: String) => {println(name)})
//1。参数的类型可以省略,会根据形参进行自动推导
f((name) => {println(name)})
//2。类型省略后,发现只有一个参数,则圆括号可以省略。其他情况,没有参数和参数超过1的永远不能省略圆括号。
f(name => {println(name)})
//3。匿名函数如果只有一行,则大括号也可以省略
f(name => println(name))
//4. 如果参数只出现一次,则参数省略且后面参数可以用_代替。
f(println(_))
//5.如果可以推断出,当前传入的println是一个函数体,而不是调用语句,可以直接省略下划线
f(println)
}
}
二元函数使用示例:
object LambdaTest {
def main(args: Array[String]): Unit = {
println("-----------------")
//定义一个二元运算函数,只操作1和2两个数,具体运算通过参数传入
def dualFunctionOneAndTwo(fun:(Int,Int)=>Int): Int = {
fun(1,2)
}
val add = (a:Int,b:Int) => a + b
val minus = (a:Int,b:Int) => a - b
println(dualFunctionOneAndTwo(add))
println(dualFunctionOneAndTwo(minus))
//二元函数简化
println("-------------二元函数简化----------")
println(dualFunctionOneAndTwo(_ + _))
println(dualFunctionOneAndTwo(_ - _))
println(dualFunctionOneAndTwo(-_ + _))
}}
输出如下所示:
-----------------
3
-1
-------------二元函数简化----------
3
-1
1
二、函数高级用法
- 函数作为值进行传递
- 函数作为参数进行传递
- 函数作为函数的返回值返回
object function3 {
def main(args: Array[String]): Unit = {
def f(n: Int): Int = {
println("f调用")
n + 1
}
val result: Int = f(123)
println(result)
//1.函数作为值进行传递
val f1: Int=>Int = f
val f2 = f _
println(f1)
println(f1(12))
println(f2)
println(f2(35))
//2.函数作为参数进行传递
def dualEval(op: (Int,Int)=>Int,a: Int,b: Int): Int ={
op(a,b)
}
def add(a: Int,b: Int): Int = {
a + b
}
println(dualEval(add,12,35))
println(dualEval((a,b) => a + b,12,35))
println(dualEval(_+_,12,35))
//3.函数作为函数的返回值返回
def f5(): Int=>Unit = {
def f6(a: Int): Unit = {
println("f6调用 "+ a)
}
f6 //将函数直接返回
}
val f6 = f5()
println(f6)
println("------------")
println(f6(25))
}
}
三、函数高级应用案例
应用案例一:
object function3 {
def main(args: Array[String]): Unit = {
val arr: Array[Int] = Array(12,45,75,98)
//对数组进行处理,将操作抽象出来,处理完毕之后的结果返回一个新的数组
def arrayOperation(array: Array[Int],op: Int=>Int): Array[Int] = {
for( elem <- array) yield op(elem)
}
//定义一个加1操作
def addOne(elem: Int): Int = {
elem + 1
}
//调用函数
val newArray: Array[Int] = arrayOperation(arr,addOne)
println(newArray.mkString(","))
//传入匿名函数,实现元素翻倍
val newArray2 = arrayOperation(arr, _ * 2)
println(newArray2.mkString(", "))
}
}
四、函数柯里化和闭包
- 闭包:函数式编程的标配
- 闭包:如果一个函数,访问到了它的外部(局部)变量的值,那么这个函数和他所处的环境,称为闭包。
object function4 {
def main(args: Array[String]): Unit = {
def addByA(a: Int): Int =>Int = {
def addB(b: Int): Int = {
a + b
}
addB
}
println(addByA(35)(24))
def addByA2(a: Int): Int=>Int = a + _
println(addByA2(3)(4))
}
}
- 函数柯里化:把一个参数列表的多个参数,变成多个参数列表。
object function4 {
def main(args: Array[String]): Unit = {
def addByA(a: Int): Int =>Int = {
def addB(b: Int): Int = {
a + b
}
addB
}
println(addByA(35)(24))
def addByA2(a: Int): Int=>Int = a + _
println(addByA2(3)(4))
def addCurrying(a: Int)(b: Int): Int = {
a + b
}
println(addCurrying(2)(3))
}
}
五、传值参数和传名参数
object function5 {
def main(args: Array[String]): Unit = {
//1.传值参数
def f0(a: Int): Unit = {
println("a " + a)
println("a " + a)
}
f0(23)
def f1(): Int = {
println("f1调用")
12
}
f0(f1)
println("---------------------------")
//2.传名参数,传递的不再是具体的值,而是代码块
def f2(a: =>Int): Unit = {
println("a: " + a)
println("a: " + a)
}
f2(23)
f2(f1())
}
}
输出如下所示:
a 23
a 23
f1调用
a 12
a 12
---------------------------
a: 23
a: 23
f1调用
a: 12
f1调用
a: 12
六、惰性加载
- 当函数返回值被声明为lazy时,函数的执行将被推迟,直到首次对此取值,该函数才会执行。这种函数称之为惰性函数。
object function5 {
def main(args: Array[String]): Unit = {
lazy val result: Int = sum(13,47)
println("1.函数调用")
println("2.result = " + result)
println("4.result = " + result)
}
def sum(a: Int, b: Int): Int = {
println("3.sum调用")
60
}
}
输出如下所示:
1.函数调用
3.sum调用
2.result = 60
4.result = 60