Scala高阶函数入门

    xiaoxiao2023-09-24  155

    文章目录

    概述1.作为值的函数2.匿名函数3.函数参数3.一些有用的高阶函数4.柯里化

    概述

    高阶函数是指使用其他函数作为参数、或者返回一个函数作为结果的函数。在Scala中函数是“一等公民”,所以允许定义高阶函数。这里的术语可能有点让人困惑,我们约定,使用函数值作为参数,或者返回值为函数值的“函数”和“方法”,均称之为“高阶函数”。

    1.作为值的函数

    在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 }

    2.匿名函数

    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) //也可以使用{}以及中置表示法(没有句点),这种方法比较常见

    3.函数参数

    (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


    3.一些有用的高阶函数

    (1 to 9).map(10* _).foreach(print) map()将一个函数应用到某个集合的所有元素并返回结果,foreach()将所有元素遍历,用print打印。(1 to 9).filter(_%2==0) //2 4 6 8 过滤可以被2 整除的数。(1 to 9).reduce(_ + _) //带两个参数的函数 遍历从左到右的所有元素,等同于(((1+2)+3)+4)+…+9,每次计算的结果赋给左边的参数,后面的赋给右边,reduce默认为reduceLeft,与reduceRight相反。 “Alice has a pretty face”.split(" ").sortWith(_.length < _.length) 输出一个按长度递增的Array数组:(a, has, face, Alice, pretty)(1 to n).foldLeft(1)(_ * _) //120 输出1-n的阶乘,若n<=1,则返回1,使用柯里化的高阶函数。

    4.柯里化

    指将原来接受两个参数的函数变成接收一个参数函数的过程: 两个参数:

    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)
    最新回复(0)