Scala--高阶函数

一、作为值的函数

  import scala.math._

  val num  = 3.14
  val func = ceil _ // _意味着确实指的是这个函数,而不是忘记了传参数 ,func是一个函数变量,内容保存的是个函数

  val v = func(num)
  println(v)
  val arr = Array(1.0,3.14,4).map(func)  //将函数func传递给map方法,将他应用到数组中的所有值,然后返回结果数组
  for(i<- arr) print(i+" ")

结果:

4.0
1.0 4.0 4.0 

二、匿名函数

  val func = (x:Double) => x*3 //匿名函数
 val arr1 = Array(2.0,4,6).map((x:Double)=> x*3) //匿名函数
  val arr2 = Array(2.0,4,6).map{(x:Double)=> x*3} //匿名函数,可以将函数用{}括起来
  val arr3 = Array(2.0,4,6) map{(x:Double)=> x*3} //匿名函数,中置表示法,可以不用句号
  for(i <- arr1) print(i+" ")

三、带函数参数的函数

  import scala.math._
  def valueAtFunc(f: (Double) => Double) = { // f: (Double) => Double 定义函数参数为 double,返回值为double
    f(0.25) //调用函数的参数为 2.0
  }

  println(valueAtFunc(ceil _))  //将函数传递个 函数valueAtFunc
  println(valueAtFunc(sqrt _))

结果:

1.0
0.5

四、参数(类型)推断

  import scala.math._
    def valueAtFunc(f: (Double) => Double) = { // f: (Double) => Double 定义函数参数为 double,返回值为double
      f(0.25) //调用函数的参数为 2.0
    }

    println(valueAtFunc(ceil _))  //将函数传递个 函数valueAtFunc
    println(valueAtFunc(sqrt _))

  valueAtFunc((x:Double) => x*3 ) //匿名函数,指定类型
  valueAtFunc((x)=>x*3)      //匿名函数,已知参数类型
  valueAtFunc(x=>x*3)        //匿名函数,已知参数类型,去掉括号
  valueAtFunc(_*3)           //使用_替换 x

  val f1 = 3 * _   //错误,没指定类型
  val f2 = 3 *(_:Double)  //ok
  val f3:(Double)=>Double = 3 * _ // ok 指定了f3类型

匿名函数简写:

valueAtFunc((x:Double) => x*3 ) //匿名函数,指定类型
valueAtFunc((x)=>x*3)      //匿名函数,已知参数类型
valueAtFunc(x=>x*3)        //匿名函数,已知参数类型,去掉括号
valueAtFunc(_*3)           //使用_替换 x

五、一些有用的高阶函数

map这个方法将一个函数应用到某个集合的所有元素并返回结果

foreach将函数应用到每个元素,并不返回结果

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

结果:


*
**
***
****
*****
******
*******
********
*********
复制代码

filter输出所有匹配某个特定条件的元素

(0 to 9).filter(_ % 2 == 0).foreach(println(_))

结果:

0
2
4
6
8

reduceLeft方法接收一个二元函数,从左到右遍历元素

println((0 to 9).reduceLeft(_ + _))   // 相当于  (...((((0+1) + 2) + 3) + 4) ...+ 9)

结果

45

sortWith方法二元排序

"I am a bad guy".split(" ").sortWith(_.length<_.length).foreach(println(_))

结果:

I
a
am
bad
guy

六、闭包

闭包由代码和代码用到的非局部变量定义构成

七、SAM转换

Single Abstract Method

八、柯里化

Currying,指的是将原本接收两个参数的函数变成新的接收一个参数的函数的过程。

  def mul(x:Int, y:Int) = x * y  //接收两个参数的函数

  def mulOneAtATime(x:Int) = (y:Int)=> x * y  //接收一个参数的函数,需要接收两次参数
  def mulOneAtATime1(x:Int)(y:Int) = x * y //柯里化 简写
  println(mulOneAtATime(3)(4))
  println(mulOneAtATime1(3)(4))

柯里化用途:

传递一个参数调用函数,有助于对参数类型进行推断,即类型推断

  val a = Array("Hello","World")
  val b = Array("hello","world")

  a.corresponds(b)(_.equalsIgnoreCase(_))

Scaladoc说明

that是String类型的序列,所以第二个函数参数是(String, String) => Boolean,所以适用函数_.equalsIgnoreCase(_)传递两个String类型参数的函数。

九、控制抽象

实现类似while条件控制,柯里化实现

  //until函数  类似于while
  def until(condition: => Boolean) (block: => Unit) { //不带参数,没有返回值的函数 block: => Unit
    if(condition){
      block
      until(condition)(block)
    }
  }

  var x:Int = 10
  until(x > 0){ //传递两个函数体, 第一个函数体当做条件,第二个函数体当做计算块
    x -= 1
    println(x)
  }

结果:

9
8
7
6
5
4
3
2
1
0

十、return表达式

  //until函数  类似于while
  def until(condition: => Boolean) (block: => Unit) { //不带参数,没有返回值的函数 block: => Unit
    if(condition){
      block
      until(condition)(block)
    }
  }

  var x:Int = 10
  until(x > 0){ //传递两个函数体, 第一个函数体当做条件,第二个函数体当做计算块
    x -= 1
    println(x)
  }

  def indexOf(str: String, ch:Char): Int ={
    var i = 0
    until( i!=str.length){
      if( str(i) == ch) return i      //return 返回给带名函数,并不返回给匿名函数 {if(str(i) == ch) return i; i+=1}的until
      i+=1
    }
    return -1
  }
  println(indexOf("Hello", 'i'))

return在控制抽象中很有用。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值