高阶函数是指使用其他函数作为参数、或者返回一个函数作为结果的函数。在Scala中函数是“一等公民”,所以允许定义高阶函数。这里的术语可能有点让人困惑,我们约定,使用函数值作为参数,或者返回值为函数值的“函数”和“方法”,均称之为“高阶函数”。
在scala中,函数就像其他数据一样,你可以在变量中存放函数:
def main(args: Array[String]): Unit = { val n = fun _ // _表示将函数fun作为一个值赋给了变量n,相当于该函数又有了一个名字n val result = n(3) println(result) //2 } def fun(x:Int): Int ={ x-1 }scala中,不需要给每个函数命名,正如你不需要给每个数字命名一样。以下是一个匿名函数:
(x:Int)=>x-1相当于把一个函数简写了:
def fun(x:Int): Int ={ x-1 }同样,匿名函数也可以赋给一个变量:
val f = (x:Double)=>x-1 Array(3.12,5.23,8.35).map(f).foreach(println) //这里map中得函数变量将集合里的每个元素-1 Array(3.12,5.23,8.35) map{f} foreach(println) //也可以使用{}以及中置表示法(没有句点),这种方法比较常见(1)基本用法:
函数既然可以被当作变量以及使用匿名函数简写,当然也能被当作参数,这便是高阶函数最终形奥义。 在一般函数中,使用的都是基本数据类型作为参数:
def fun(a:Int,b:Double):Double={ a+b }把简写的函数当作参数和基本参数放进一个函数(高阶)里,解决更复杂的逻辑:
def fun(x: Int, f: (Double) => Double): Double = f(x)一般格式: def 函数名 (…,函参名(参数类型)=>结果类型)=表达式/调用函数参数
(2)产生新的函数
def main(args: Array[String]): Unit = { val newfun = mulFun(5) //这里返回了一个5*x的函数 print(newfun(3)) //15 } def mulFun(factoy:Int)=(x:Int)=>x*factoy //返回一个匿名函数疑问:这和在普通函数里调用其他函数有什么不一样吗?
如果将一个数值9和一个函数Math.sqrt传入上述高阶函数中: val res = fun(9, Math.sqrt) //3.0 或者将9和自定义的平方函数传入: val res = fun(9,(x:Double)=>x*x) //81.0结论:普通方法只能一次性的调用一种功能,高阶函数通过传入不同的函数参数可以自由选择,完成更多种功能,更灵活多变一些。
(3)自动推断 当你将一个匿名函数当作参数传给另一个函数时,scala会自动帮你推断函数的类型信息: 比如,你的代码原本是这样的: val res = fun(9,(x:Double)=>x*2) 可以写成这样: val res = fun(9,_*2) 注意:只有当参数只在后面出现一次,才能用_替代
从舒适度上来讲,这是终极版本了,但前提是这些简写方式在参数类型已知的情况下有效: val fun = _ *2 //错误,无法推断 val fun = (_:Double)*3 // ok
指将原来接受两个参数的函数变成接收一个参数函数的过程: 两个参数:
def mul(x:Int,y:Int) = x*y一个参数,返回一个函数:
def mul(x:Int) = (y:Int) => x*y要计算两个数二点乘积,你需要调用:
mul (2)(3) //6最终形态——scala支持如下的简写来定义这样的柯里化函数:
def mul(x:Int)(y:Int)=x*y //调用 mul(2)(3)