Scala中偏函数


Scala-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函数的参数传入类型一致,不然会编译报错
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值