scala unapply返回boolean

时间:2013-09-11 13:56:43

标签: scala pattern-matching unapply

阅读this,我仍然对unapply()返回Boolean有疑问。

如果要查看 Scala编程手册(第2版),第602页 。有一个例子:

case Email(Twice(x @ UpperCase()), domain) => ...

将UpperCase定义为unapply()返回Boolean但没有apply()的对象

object UpperCase {
 def unapply(s:String): Boolean = s.toUpperCase == s
}

其中Twice是这样的:

object Twice {
 def apply(s:String): String = s + s
 ...

问题是(必须太多,对不起):

UpperCase()。unapply(..)如何在这里工作?

如果我通过:DIDI@hotmail.com,然后x在第一个代码段='DI'..那么我们使用'@'..来绑定'x'将其传递给{{1}调用UpperCase.unapplyunapply(x)(?)然后返回unapply('DIDI')

但为什么不True?我倾向于认为Option返回unapply ..它是如何工作的一种方式。这可能是因为通常Option包装了一些数据,但是对于简单的情况我们不应该包装boolean?因为我们没有申请()?

使用Option / Boolean时有何不同?基于这个例子。

这个语法:Option,如果我们在一个特定的x @ UpperCase()内进行匹配,它应该替换value match case(这是我想要读取它的方式吗?)语法?它似乎不是这样做的统一方式/语法。

通常语法(假设x,y为Int):case表示case AA(x @ myX, y) => println("myX: " + myX)绑定到x,基本上myXmyX的别名.. 在这种情况下。但在我们的案例中 - xx @ UpperCase()绑定到x ..将UpperCase().unapply()作为参数。我的意思是绑定在这里是相当抽象/广泛的概念..

2 个答案:

答案 0 :(得分:6)

这很简单:

1)如果你返回布尔,你的unapply只会测试匹配的查询

scala> object UpperCase {
     | def unapply(s: String) = s.toUpperCase == s
     | }
defined module UpperCase

scala> "foo" match {
     | case UpperCase() => true
     | case _ => false
     | }
res9: Boolean = false

2)如果您返回选项[T] ,则会创建一个解包器,用于解包T

scala> object IsUpperCase {
     | def unapply(s: String) = Option(s).map(x => x.toUpperCase == x)
     | }
defined module IsUpperCase

scala> "FOO" match {case IsUpperCase(flag) => flag}
res0: Boolean = true

答案 1 :(得分:2)

这不是那么简单。

“布尔测试”匹配的行为刚刚在最新的里程碑中更改:

apm@mara:~/clones/scala$ ./build/pack/bin/scala
Welcome to Scala version 2.11.0-20130911-042842-a49b4b6375 (OpenJDK 64-Bit Server VM, Java 1.7.0_25).
Type in expressions to have them evaluated.
Type :help for more information.

scala> 

scala> object OK { def unapply(s: String) = Some(s) filter (_ == "OK") }
defined object OK

scala> import PartialFunction._
import PartialFunction._

scala> cond("OK") { case OK() => true }
<console>:12: error: wrong number of patterns for object OK offering String: expected 1, found 0
              cond("OK") { case OK() => true }
                                ^
<console>:12: error: wrong number of patterns for object OK offering String: expected 1, found 0
              cond("OK") { case OK() => true }
                                  ^

scala> cond("OK") { case OK(x) => true }
res1: Boolean = true

scala> :q

以前,您可以使用提取器而不提取任何字段,仅用于“布尔测试”,即使unapply的结果不是Boolean

apm@mara:~/clones/scala$ scalam
Welcome to Scala version 2.11.0-M4 (OpenJDK 64-Bit Server VM, Java 1.7.0_25).
Type in expressions to have them evaluated.
Type :help for more information.

scala> import PartialFunction._
import PartialFunction._

scala> object OK { def unapply(s: String) = Some(s) filter (_ == "OK") }
defined object OK

scala> cond("OK") { case OK() => true }
res0: Boolean = true

scala> cond("OK") { case OK(x) => true }
res1: Boolean = true

Here is some discussionhere is the change处理提取器签名的方式。