2

读到这里unapply(),我仍然对那个回报有疑问Boolean

如果看看Scala Programming Book (2nd edition), page 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' 将其传递UpperCase.unapply给调用unapply(x)ie unapply('DIDI')(?) 然后它返回True

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

有什么区别,什么时候使用Boolean/ Option?基于这个例子。

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

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

4

2 回答 2

6

这很简单:

1)如果你返回Boolean,你的 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)如果你返回Option[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
于 2013-09-11T14:30:24.400 回答
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

以前,您可以在不提取任何字段的情况下使用提取器,仅用于“布尔测试”,即使 is 的结果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

这是一些讨论这里是提取器签名处理方式的变化。

于 2013-09-11T16:13:21.710 回答