美文网首页
Scala基础——高阶函数

Scala基础——高阶函数

作者: _羊羽_ | 来源:发表于2019-08-09 00:02 被阅读0次

    函数字面量

    在非函数式编程语言里,函数的定义包含了“函数类型”和“值”两种层面的内容。但是,在函数式编程中,函数是“头等公民”,可以像任何其他数据类型一样被传递和操作,也就是说,函数的使用方式和其他数据类型的使用方式完全一致了。这时,我们就可以像定义变量那样去定义一个函数,由此导致的结果是,函数也会和其他变量一样,开始有“值”。就像变量的“类型”和“值”是分开的两个概念一样,函数式编程中,函数的“类型”和“值”也成为两个分开的概念,函数的“值”,就是“函数字面量”。
    整数字面量

    scala> val i = 1
    i: Int = 1
    

    浮点数字面量

    scala> val f = 3.1415
    f: Double = 3.1415
    

    布尔型字面量

    scala> val b = true
    b: Boolean = tru
    

    字符字面量

    scala> val c = 'A'
    c: Char = A
    

    字符串字面量

    scala> val s ="hello world"
    s: String = hello world
    

    匿名函数

    不需要给每个函数命名,可以使用匿名函数,匿名函数的定义形式,称为“Lambda表达式”。“Lambda表达式”的形式如下:

    (参数名称:参数类型...) => 表达式 
    

    eg:

    scala> (x:Int)=>x+1
    res0: Int => Int = $$Lambda$1035/481792876@35342d2f
    

    把匿名函数传递一个函数

    scala> val m = (x:Int) => x+1
    m: Int => Int = $$Lambda$1046/2013613908@cb7fa71
    
    scala> m(2)
    res1: Int = 3
    

    把匿名函数存放到变量中,addFunc是计算2个数的和,下面是在Scala解释器中的执行过程:

    scala> val addFunc = (a:Int,b:Int) => a+b
    addFunc: (Int, Int) => Int = $$Lambda$1052/1403539444@7ce85af2
    scala> println(addFunc(1,2))
    3
    

    currying柯里化

      def sum (a:Int,b:Int)= a+b
      def sumCurrying (a:Int)(b:Int)= a+b
      def main(args: Array[String]): Unit = {
        println(sum(1,2))
        println(sumCurrying(1)(2))
      }
    

    高阶函数

    一个接受其他函数作为参数或者返回一个函数的函数就是高阶函数。

    占位符语法

    使用下划线作为一个或多个参数的占位符,只要每个参数在函数字面量内仅出现一次。

    scala> val list = List(1,2,3,4,5)
    list: List[Int] = List(1, 2, 3, 4, 5)
    
    scala> list.filter(x => x>3)
    res2: List[Int] = List(4, 5)
    
    scala> list.filter(_ > 3)
    res3: List[Int] = List(4, 5)
    

    x => x>3和_ > 3是等价的,当采用下划线的表示方法时,对于列表list中的每个元素,都会依次传入用来替换下划线,首先传入1,然后判断1>3是否成立,如果成立,就把该值放入结果集合,如果不成立,则舍弃,接着再传入2,然后判断2>3是否成立,依此类推。最终符合结构的就是4和5了

    map

    逐个操作集合中的每个元素

    scala>  val l = List(1,2,3,4)
    l: List[Int] = List(1, 2, 3, 4)
    
    scala> l.map((x:Int)=>x+1)
    res2: List[Int] = List(2, 3, 4, 5)
    

    可以省略参数类型

    scala> l.map((x) =>x+1)
    res3: List[Int] = List(2, 3, 4, 5)
    

    如果只有一个参数,也可以省略小括号

    scala> l.map(x =>x+1)
    res4: List[Int] = List(2, 3, 4, 5)
    

    使用_占位符代表参数

    scala> l.map(_+1)
    res8: List[Int] = List(2, 3, 4, 5)
    

    filter

    scala> l.filter(_ %2==0)
    res10: List[Int] = List(2, 4)
    

    take

    scala> l.take(2)
    res12: List[Int] = List(1, 2)
    

    reduce

    处理列表的每个元素并返回一个值。通过使用reduceLeft和reduceRight我们可以强制处理元素的方向。(使用reduce方向是不被保证的)

    scala> l.reduce(_+_)
    res13: Int = 10
    

    reduceLeft和reduceRight


    image.png
    scala> l.reduceLeft(_-_)
    res14: Int = -8
    
    scala> l.reduceRight(_-_)
    res15: Int = -2
    

    fold折叠

    fold操作需要从一个初始的“种子”值开始,并以该值作为上下文,处理集合中的每个元素。

    scala> val list = List(1,2,3,4,5)
    list: List[Int] = List(1, 2, 3, 4, 5)
    
    scala> list.fold(6)(_+_)
    res18: Int = 21
    

    fold函数实现了对list中所有元素的累乘操作。fold函数需要两个参数,一个参数是初始种子值,这里是6,另一个参数是用于计算结果的累计函数,这里是累加。执行list.fold(6)(+)时,首先把初始值拿去和list中的第一个值1做加法操作,得到累加值7,然后再拿这个累加值7去和list中的第2个值2做累加操作,得到累加值9,依此类推,一直得到最终的累乘结果21。

    scala> list.foldLeft(6)(_-_)
    res20: Int = -9
    
    scala> list.foldRight(6)(_-_)
    res21: Int = -3
    
    def foldRight[B](z: B)(op: (A, B) => B): B =
    reversed.foldLeft(z)((x, y) => op(y, x))
    

    相关文章

      网友评论

          本文标题:Scala基础——高阶函数

          本文链接:https://www.haomeiwen.com/subject/stserctx.html