Scala学习笔记(1)

PartialFunction[-A, +B]函数的使用

转载记得注明出处
blog.csdn.net/isinstance/article/details/51809687

在Scala的文档中,是这样解释PartialFunction的:

PrartialFunction[-A,+B]型的一元偏函数的域并不一定包括所有A型的值,函数isDefinedAt允许动态的测试如果函数的值在这个域内。

即使a:AisDefinedAt返回true,调用apply(a)仍然有可能抛出异常,下面的代码是合法的。

调用者有责任调用isDefinedAtapply之前,因为如果isDefinedAt如果失败了,不能保证apply将抛出一个错误来指示错误条件。

如果不抛出一个错误,结果的赋值可能是一个任意的值。

PartialFunctionscala.Function1最主要的区别在于,使用PartialFunction可以选择输入,然后宣称在其域内要做的不同的事情。

scala的官方文档给了一个实例代码

val sample = 1 to 10 //创建一个Range从1到10
val isEven: PartialFunction[Int, String] = {
  case x if x % 2 == 0 => x+ " is even" //匹配x,如果x能整除2的话,也就是如果x所偶数的话
}

val evenNumber = sample collect isEven //collect方法可以使用isDefinedAt来选择要收集的成员

val isOdd: PartialFunction[Int, String] = {
  case x if x % 2 == 1 => x+ " is odd"
}

val numbers = sample map (isEven orElse isOdd)//方法orElse允许链接一个偏函数来处理超出声明域的输入

然后我们来实际测试一下代码
首先输入

val sample = 1 to 10

输出如下

scala> val sample = 1 to 10
sample: scala.collection.immutable.Range.Inclusive = Range(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)

这一步不用过多的说明了

输入

val isEven: PartialFunction[Int, String] = {
  case x if x % 2 == 0 => x+ " is even"
}

输出

isEven: PartialFunction[Int,String] = <function1>

然后我们试试这个

val evenNumber = sample collect isEven

输出

evenNumber: scala.collection.immutable.IndexedSeq[String] = Vector(2 is even, 4 is even, 6 is even, 8 is even, 10 is even)

可以看出,对sample中的每个元素带进isEven函数,然后再调用了collect之后,输出所有的偶数

我们继续定义isOdd
然后输出

val numbers = sample map (isEven orElse isOdd)

输出

numbers: scala.collection.immutable.IndexedSeq[String] = Vector(1 is odd, 2 is even, 3 is odd, 4 is even, 5 is odd, 6 is even, 7 is odd, 8 is even, 9 is odd, 10 is even)

已经通过这两个函数自动将偶数和奇数标记了出来

而定义函数的时候的PartialFunction[Int, String]指名我们要输入的是一个Int类型,输出的是一个String类型

现在我们来看一个在Programming Scala书中的例子

//匹配s,如果s是String类型的话,输出Yes
}
val pf2: PartialFunction[Any, String] = {
  case d: Double => "Yes"//匹配d,如果d是Double类型的话,输出Yes
}

val pf = pf1 orElse pf2//将这两个函数结合,得到一个新的偏函数

def tryPF(x: Any, f: PartialFunction[Any, String]): String = try {
  f(x).toString
} catch {
  case _: MatchError => "ERROR!"
}

def d(x: Any, f: PartialFunction[Any, String]) = f.isDefinedAt(x).toString

List("str", 3.14, 10) foreach {
  x =>
  printf("%-5s %-5s %-6s %-5s %-6s %-5s %-6s\n", x.toString, d(x, pf1), tryPF(x, pf1), d(x, pf2), tryPF(x, pf2), d(x, pf), tryPF(x, pf))
} 

我们一步一步来测试代码

scala> val pf1: PartialFunction[Any, String] = {
     | case s:String => "Yes"
     | }
pf1: PartialFunction[Any,String] = <function1>

scala> val pf2: PartialFunction[Any, String] = {
     | case d:Double => "Yes"
     | }
pf2: PartialFunction[Any,String] = <function1>

scala> val pf = pf1 orElse pf2
pf: PartialFunction[Any,String] = <function1>
scala> def tryPF(x: Any, f: PartialFunction[Any, String]): String = try { f(x).toString } catch { case _:MatchError => "Error!" }
tryPF: (x: Any, f: PartialFunction[Any,String])String
scala> def d(x: Any, f: PartialFunction[Any, String]) = f.isDefinedAt(x).toString
d: (x: Any, f: PartialFunction[Any,String])java.lang.String
scala> List("str", 3.14, 10) foreach {
     |   x =>
     |   printf("%-5s %-5s %-6s %-5s %-6s %-5s %-6s\n", x.toString, d(x, pf1), tryPF(x, pf1), d(x, pf2), tryPF(x, pf2), d(x, pf), tryPF(x, pf))
     | } 
str   true  Yes    false Error! true  Yes   
3.14  false Error! true  Yes    true  Yes   
10    false Error! false Error! false Error!

注意:

第一列的值str, 3.14, 10都属于x.toString生成的

由此可以看出,未输入字符串时候,pf1将会失败,未输入Double数字时,pf2会失败,如果给的是Int数字,两个都会失败

组合后的pf函数,对于字符串和Double都会成功,但是输入Int类型数字时,依旧会失败

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值