scala之Scala 中的魔术 PartialFunction

bhlsheji 阅读:14 2024-09-07 23:24:14 评论:0

我不认为这段代码应该有效,但它确实有效(在 Scala 2.10 中):

scala>     ((i: Int) => i.toString match { 
     |        case s if s.length == 2 => "A two digit number" 
     |        case s if s.length == 3 => "A three digit number" 
     |     }): PartialFunction[Int,String] 
res0: PartialFunction[Int,String] = <function1> 
 
// other interactions omitted 
 
scala> res0.orElse(PartialFunction((i: Int) => i.toString)) 
res5: PartialFunction[Int,String] = <function1> 
 
scala> res5(1) 
res6: String = 1 

它是如何工作的?我希望 MatchError 被抛入 res0

Scala 语言规范似乎没有明确说明 res0 应该如何解释。

请您参考如下方法:

诀窍是编译器不会将您的定义解释为转换为部分函数的总函数——它实际上首先创建了一个部分函数。您可以通过注意 res0.isDefinedAt(1) == false 来验证。

如果您实际将全函数转换为偏函数,您将获得预期的行为:

scala> PartialFunction((i: Int) => i.toString match { 
     |       case s if s.length == 2 => "A two digit number" 
     |       case s if s.length == 3 => "A three digit number" 
     |     }) 
res0: PartialFunction[Int,String] = <function1> 
 
scala> res0 orElse ({ case i => i.toString }: PartialFunction[Int, String]) 
res1: PartialFunction[Int,String] = <function1> 
 
scala> res1(1) 
scala.MatchError: 1 (of class java.lang.String) 
// ... 

在此示例中,PartialFunction.apply 将其参数视为一个总函数,因此有关其定义位置的任何信息都将丢失。


标签:Scala
声明

1.本站遵循行业规范,任何转载的稿件都会明确标注作者和来源;2.本站的原创文章,请转载时务必注明文章作者和来源,不尊重原创的行为我们将追究责任;3.作者投稿可能会经我们编辑修改或补充。

关注我们

一个IT知识分享的公众号