Scala高阶函数

高阶函数

  • 头等函数
    • 在Sacla中,函数可以像其他数据类型一样被传递和操作,也就是说函数就是一个值。

      import scala.math._
      val num = 3.14
      val fun = ceil _  // _ 意思是将ceil方法转换成函数,在Scala中无法直接操作方法,只能直接操作函数。
      fun(num)  // 4.0 由于上一步把妇女设为ceil函数,所以fun的用法和普通的函数调用方法一样。而区别在于fun是一个包含函数的变量,不是一个固定的函数
      
      // 也可以把fun传递给另一个函数
      Array(1.1, 2.2, 3.3, 4.4) map fun
      
      // 也可以这么用
      def add(a: Int, b:Int): Int = a + b
      val fun1 = add _
      

      对一个函数而言,我们能做的事情只有两种:

      1. 调用它
      2. 传递它,存放在变量中,或者作为参数传给另一个函数
  • 匿名函数
    • 匿名函数的作用域很小,一般把匿名函数作为另一个函数的参数使用

      
      val add = (a: Int, b: Int) => a + b  // 等号右边是一个求和的匿名函数
      Array(1, 2, 3, 4) map { (x:Int) => x * 3 }  // 也可以把匿名函数传递给另一个函数
      
    • 带函数参数的函数(高阶函数)

    // 这里的参数是任何可以接受Double类型参数并返回Double类型值的函数。quarter的类型为:((Double) => Double) => Double
    def quarter(f: (Double) => Double)  = f(1.5)
    // 调用
    quarter(ceil _)
    quarter(sqrt _)
    
    • 高阶函数可以产出另一个函数

      def mul(factor: Double) = (x: Double) => factor * x
      
      val fun = mul(3.14)     // mul返回一个匿名函数,fun = (x: Double) => 3.14 * x
      fun(3.14)
      

      mul的类型为(Double) => ((Double) => Double)

  • 参数类型推断
  • 如果把一个匿名函数传递给另一个函数或者方法时,Scala会进行类型推断

    def solution(f: (Int) => Int) = f(3)
    
  • 一般会这么调用上面的方法

    solution((x: Int) => x * 3)  // 传递了一个匿名函数(x:Int)=> x * 3
    
  • 由于solution方法在定义时知道了会传入一个类型为(Int)=> Int 的函数,所以可以简写成
solution((x) => x * 3)
  • 当函数只有一个参数时可以这样写
solution(x => x * 3)
  • 如果参数在=>右边只出现一次,还能更简单
solution(3 * _)

  • 一些常用的高阶函数
    1 to 3 map { 0.1 * _ }  // Vector(0.1, 0.2, 0.3)
    1 to 3 map { "*" * _ } foreach { println _ }    // 打印三角形
    1 to 9 filter { _ % 2 == 0 }    // 过滤出偶数
    1 to 3 reduceLeft { _ * _ }     // 3的阶乘
    // Array(C, Java, Scala, Python, JavaScript)
    "Scala Java C Python JavaScript" split { " " } sortWith { _.length < _.length}
    
    • ruduceLeft方法接受一个带有两个参数的函数(二元函数),并将它应用到序列的所有元素

    • sortWith接受两个参数,并按长度排序

  • 柯里化
    • 柯里化是指,将原来接受两个参数的函数变成新的接受一个参数的函数的过程。新的函数返回以原有第二个参数作为参数的函数
     def add(a: Int, b: Int) = a + b
     add(1, 2) 
    
     // 柯里化
     def add(a: Int) = (b: Int) => a + b
     add(1)(2)   
    
     // Scala支持如下写法定义柯里化函数
     add(a: Int)(b: Int) = a + b
    
     add(1)(2)
     或
     val plus = add(1)_  // _代表占位符
     plus(2)
    
  • 控制抽象

  • 在Scala中可以将一系列语句组成不带参数也没有返回值的函数

   def run(block: () => Unit) = block()    // 参数block是类型为 () => Unit的函数
   run { () => println("Hello Word!") }    // () => println("Hello Word!")是匿名函数

   // 使用换名调用发声明函数:在参数声明和调用该函数参数的地方省略(),保留 =>
   def run(block: => Unit) = block
   run { println("Hello Word!") }
  • Scala中能够构建控制抽象:看上去像是编程语言关键字的函数。例如实现一个用起来和while一样的函数
    def when(condition: => Boolean)(block: => Unit) {       // 柯里化的函数when
      if(condition) { 
        block
        when(condition)(block) 
      }
    }
    //也可以用下面的写法,但是要指明返回值类型
     def when(condition: => Boolean)(block: => Unit): Unit = if (condition) { block; when(condition)(block) }

    // 用法
    var x = 3
    when(x > 0){
      println("Hello Word!")
      x -= 1
    }

你可能感兴趣的:(Scala高阶函数)