高阶函数主要有两种:

一、将一个函数当做另外一个函数的参数(即函数参数)

普通函数的定义语法如下:

def funName(para1:Type1,para2:Type2):Type = { do some things }

我们想象一下,如果将函数作为参数,那么函数的类型该怎么写呢?

函数的类型,其实就是输入输出的类型。

假设,我们需要将函数ceil作为参数,而ceil的定义如下

  def ceil(x: Double): Double  = java.lang.Math.ceil(x)

那我们可以用如下方法定义函数

    def valueForCeil(f:(Double)=>Double,value:Double)={
      f(value)
    }

f是参数名称,(Double)=>Double 是参数的类型。


我们该如何调用函数valueForCeil呢?

package com.dt.scala.hello
import scala.math._

object ScalaInAction {
    def valueForCeil(f:(Double)=>Double,value:Double)={
      f(value)
    }                                             //> valueForCeil: (f: Double => Double, value: Double)Double
    valueForCeil(ceil _, 0.25)                    //> res0: Double = 1.0
}

第一个参数传入ceil函数,要让编译器知道ceil是函数,必须使用偏函数的方式:ceil _ 


其实,我们可以看出valueForCeil的第一个参数,并不是非要传入函数ceil。只要函数的定义参数类型和返回值于ceil一样,就可以。

看如下例子:

package com.dt.scala.hello
import scala.math._

object ScalaInAction {
    def valueForCeil(f:(Double)=>Double,value:Double)={
      f(value)
    }                                             //> valueForCeil: (f: Double => Double, value: Double)Double
    valueForCeil(sqrt _, 0.25)                    //> res0: Double = 0.5
}


这样我们就能很容易理解函数参数啦~


二、返回值是函数的函数

这个函数也是一样,只要理解了返回值是类型一个匿名函数就行了。

如下:

    def addBy(factor:Int) = {
      (x:Double)=> factor + x
    }

(x:Double) 是返回函数的参数定义,返回类型由表达式 factor +x 来决定。如果表达式比较复杂,也可以如下写法

(x:Double)=> { do some things }

我们看看如何调用函数

package com.dt.scala.hello
import scala.math._

object ScalaInAction {
    def addBy(factor:Int) = {
      (x:Double)=> factor + x
    }                                             //> addBy: (factor: Int)Double => Double

    val addFive = addBy(5)                        //> addFive  : Double => Double = <function1>
    println(addFive(20))                          //> 25.0
}


scala中提供的很多函数都是高阶函数:

这里写图片描述

(1 to 9).map(x=>"*" * x).foreach(println)

map函数既是函数参数函数。

x=>"*" * x

就是一个匿名函数

如何函数就一个参数,那么可以简写成如下方式

(1 to 9).map("*" * _).foreach(println)