Scala入门之部分应用函数与偏函数

Scala入门之部分应用函数与偏函数

标签: scala函数
332人阅读 评论(0) 收藏 举报
本文章已收录于:
分类:

1.部分应用函数

部分应用函数(Partial Applied Function)是指缺少部分参数的函数.
package com.dt.scala.moguyun

/**
  * 部分应用函数
  * Created by Administrator on 2016/8/10.
  */
object PartialAppliedFunctionLearn {
  def main(args: Array[String]) {
    //第一种常见样式
    val result = sum _ //表明是一个部分应用函数,参数一个都没定
    val r = result(2)(3)(4)
    println(r)
    val r1 = result(1)//返回一个function1
    println(r1)
    val r2 = result(2)(_: Int)(4)
    println(r2)//返回一个function1
    val r3 = r2(5)//完整
    println(r3)

    //第二种常见样式
    val s = sum(4)(8)(_: Int)//注意这里得用_通配符,用i,j等不可以
    val s1 = s(7)
    println(s1)

    val s2 = sum(5)(_: Int)(_: Int)//返回一个function2
    println(s2)
    val s3 = s2(5, 3) //注意这里传入一个(Int, Int),而不是这样(5)(3)
    println(s3)
  }

  /**
    * 定义一个函数,要求传入三个Int类型参数
    */
  def sum(i: Int)(j: Int)(k: Int): Int ={
    i + j + k
  }
}

    
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38

结果如下:

9
<function1>
<function1>
11
19
<function2>
13

2.偏函数

偏函数是只对函数定义域的一个子集进行定义的函数。这知识点是难点,自己也没能很好理解怎么用,什么时候用 -_-!
记得学线程的时候有个receive和react ,当时老师说这个是偏函数,也没懂什么意思。看源码
    def receive[R](f : scala.PartialFunction[scala.Any, R]) : R = { /* compiled code */ }
    override def react(handler : scala.PartialFunction[scala.Any, scala.Unit]) : scala.Nothing = 
这里的参数都是scala.PartialFunction类型的,泛型参数里第一个表示输入的类型,第二个表示输出的类型。
其实在下面代码中
class HelloActor extends Actor{
  override def act(): Unit = {
    while (true) {
      //receive从邮箱中获取一条消息
      //然后传递给它的参数
      //该参数是一个偏函数
      receive {
        case "actorDemo" => println("receive....ActorDemo")
      }
    }
  }
}
    
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12

这里写图片描述
可以从上面图片中看出receive的参数是一个偏函数,输入参数是”actorDemo”,输出参数是Unit.可以理解case就是一个函数,经常有好多组case,如果一组case语句没有涵盖所有的情况,那么这组case语句就可以被看做是一个偏函数。
按我的理解,偏函数直接使用时像模式匹配,而偏函数作为参数传入时就难理解,更难应用。(以后再学怎么用),下面是自己写的代码,当作认识偏函数

package com.dt.scala.moguyun

/**
  * 偏函数
  * Created by hlf on 2016/8/10.
  */
object PartialFunctionLearn {
  def main(args: Array[String]): Unit = {
    jump("hello")
    //    jump(5)不是String直接报错
    //因为加了其余情况时会输出,如果不加其余情况的匹配会报错:
    //Exception in thread "main" scala.MatchErro
    jump("love")

    println(run(5))

    //定义时也可以用val来定义
    val jump2: PartialFunction[String, Unit] = {
      case "hello" => println("fine, and you?")
      case "have a good day!" => println("the same to you!")
      //    case 5 => println("why get me a Five?")
      case _ => println("what is this? get away from me!")
    }

    jump2("have a good day!")


  }

  /**
    * 定义一个偏函数,有两种方式定义偏函数,下面这种更好,
    * 因为有isDefinedAt方法来校验参数是否会得到处理.
    * 或者在调用时使用一个orElse方法,该方法接受另一个偏函数,
    * 用来定义当参数未被偏函数捕获时该怎么做
    */
  def jump: PartialFunction[String, Unit] = {
    case "hello" => println("fine, and you?")
    case "have a good day!" => println("the same to you!")
    //    case 5 => println("why get me a Five?")
    case _ => println("what is this? get away from me!")//注释的话如果匹配不上会报错
  }


  /**
    * 另一种定义一个偏函数的方式,不细说
    */
  def run = (x: Int) => x match {
    case x if x > 1 => 1
  }


}
结果
fine, and you?
what is this? get away from me!
1
the same to you!
    
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57

什么时候该使用偏函数?
当我们确定我们的程序不会被传入不可处理的值时,我们就可以使用偏函数。这样万一程序被传入了不应该被传入的值,程序自动抛出异常,而不需要我们手工编写代码去抛出异常,减少了我们的代码量。(不全)

3.蘑茹云代码

package com.dt.spark.scala.bascis

object HelloPartionalFunction {
  def main(args: Array[String]): Unit = {
    val sample =1 to 10
    val isEven:PartialFunction[Int,String]={
      case x if x % 2 == 0 =>   x + "is even" 
        }
    isEven(4)
    val evenNumbers = sample collect isEven
    evenNumbers.foreach { println }
     val isOdd:PartialFunction[Int,String]={
      case x if x % 2 == 1 =>   x + "is Odd" 
        }

     val numbers =sample map {isEven orElse isOdd}
     numbers.foreach { println }
  }
}





2is even
4is even
6is even
8is even
10is even
1is Odd
2is even
3is Odd
4is even
5is Odd
6is even
7is Odd
8is even
9is Odd
10is even
    
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39

以上蘑茹云代码来自[DT大数据梦工厂]首席专家Spark专家王家林老师的课程分享。感谢王老师的分享,更多精彩内容请扫描关注[DT大数据梦工厂]微信公众号DT_Spark

1
0
 
 
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符  | 博主筛选后可见
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值