• Partial Functions(偏函数)


    如果你想定义一个函数,而让它只接受和处理其参数定义域范围内的子集,对于这个参数范围外的参数则抛出异常,这样的函数就是偏函数(顾名思异就是这个函数只处理传入来的部分参数)。

    偏函数是个特质其的类型为PartialFunction[A,B],其中接收一个类型为A的参数,返回一个类型为B的结果。
    其有个重要的函数就是:
    1
    def isDefinedAt(x: A): Boolean //作用是判断传入来的参数是否在这个偏函数所处理的范围内
    定义一个普通的除法函数:
    1
    2
    3
    4
    5
    scala> val divide = (x : Int) => 100/x
    divide: Int => Int = <function1>
    输入参数0
    scala> divide(0)
    java.lang.ArithmeticException: / by zero 
    显然,当我们将0作为参数传入时会报错,一般的解决办法就是使用try/catch来捕捉异常或者对参数进行判断看其是否等于0;但是在Scala的偏函数中这些都已经封装好了,如下:将divide定义成一个偏函数()
    1
    2
    3
    4
    val divide = new PartialFunction[Int,Int] {
    def isDefinedAt(x: Int): Boolean = x != 0 //判断x是否等于0,当x = 0时抛出异常
    def apply(x: Int): Int = 100/x
    }  
    但是,当偏函数与case语句结合起来就能使代码更简洁,如下:
    1
    2
    3
    val divide1 : PartialFunction[Int,Int] = {
    case d : Int if d != 0 => 100/d //功能和上面的代码一样,这就是偏函数的强大之处,方便,简洁!!
    } 
    其实这代码就是对上面那段代码的封装,这里同样调用isDefinedAt方法
    1
    2
    3
    4
    5
    scala> divide1.isDefinedAt(0)
    res1: Boolean = false
      
    scala> divide1.isDefinedAt(10)
    res2: Boolean = true 
    再举个与case结合使用的例子:
    1
    2
    3
    4
    5
    val rs : PartialFunction[Int , String] = {
    case 1 => "One"
    case 2 => "Two"
    case _ => "Other"
    }
    输入:
    1
    2
    3
    4
    5
    6
    7
    8
    scala> rs(1)
    res4: String = One
      
    scala> rs(2)
    res5: String = Two
      
    scala> rs(100)
    res6: String = Other
     
    OrElse
    OrElse方法可以将多个偏函数组合起来使用,结合起来的效果类似case语句,但是每个偏函数里又可以再使用case
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    scala> val or1 : PartialFunction[Int,String] = {case 1 => "One"}
    or1: PartialFunction[Int,String] = <function1>
      
    scala> val or2 : PartialFunction[Int,String] = {case 2 => "Two"}
    or2: PartialFunction[Int,String] = <function1>
      
    scala> val or_ : PartialFunction[Int,String] = {case _ => "Other"}
    or_: PartialFunction[Int,String] = <function1>
      
    scala> val or = or1 orElse or2 orElse or_ //使用orElse将多个偏结合起来
    or: PartialFunction[Int,String] = <function1>
      
    scala> or(1)
    res7: String = One
      
    scala> or(20)
    res9: String = Other
    orElse还可以直接连接case使用
    1
    2
    3
    4
    5
    6
    7
    8
    9
    scala> val orCase:(Int => String) = or1 orElse {case _ => "Other"}
    orCase: Int => String = <function1>
      
    scala> orCase(1)
    res10: String = One
      
    scala> orCase(10)
    res11: String = Other
       
     
    andThen
    对函数的结果进行下一步的处理
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    scala> val at1 : PartialFunction[Int,String] = {case cs if cs == 1 => "One"}
    at1: PartialFunction[Int,String] = <function1>
      
    scala> val at2 : PartialFunction[String,String] = {case cs if cs eq "One" => "The num is 1"}
    at2: PartialFunction[String,String] = <function1>
      
    scala> val num = at1 andThen at2
    num: PartialFunction[Int,String] = <function1>
      
    scala> num(1)
    res18: String = The num is 1
     
    注意:at1函数的结果返回类型必须和at2函数的参数传入类型一致,不然会编译报错
  • 相关阅读:
    iOS开发- 蓝牙后台接收数据(BLE4.0)
    代码优化之减少重复代码-实践
    微信iOS多设备多字体适配方案总结
    iOS微信小视频优化心得
    iOS项目工程及目录结构
    手机淘宝 521 性能优化项目揭秘
    最大连续和
    struts2入门
    Maven环境搭配及继承
    easyui高级控件
  • 原文地址:https://www.cnblogs.com/yejibigdata/p/6481890.html
Copyright © 2020-2023  润新知