问题
Why can't I bind the variable in @-style when the extractor return Option[<Type>]
? I.e. this one does not work:
object IsUpperCase {
def unapply(s: String): Option[String] = {
if (s.toUpperCase() == s) {
Some(s)
} else {
None
}
}
}
val s = "DuDu@qwadasd.ru"
s match {
case u @ IsUpperCase() => println("gotcha!") // what? "wrong number of arguments for object IsUpperCase"?
case _ =>
}
But this one works!
val s = "DuDu@qwadasd.ru"
s match {
case IsUpperCase(u) => println("gotcha!")
case _ =>
}
From the other hand, if IsUpperCase
looks like this:
object IsUpperCase {
def unapply(s: String): Boolean = {
return s.toUpperCase() == s
}
}
Then the first example works, and the second does not! Why is it this way?
回答1:
what? "wrong number of arguments for object IsUpperCase"?
case u @ IsUpperCase() => println("gotcha!")
Well, yes. The return type of unapply
is Option[String]
, which means the pattern match of IsUpperCase
must accept a parameter, like this:
case u @ IsUpperCase(_) => println("gotcha!") // I don't care about the parameter
The unapply
definition that fits the first pattern is this:
object IsUpperCase {
def unapply(s: String): Boolean = s.toUpperCase() == s
}
That can be used to pattern match against IsUpperCase()
.
回答2:
Because for the first example you need to write something like case u @ IsUpperCase(v) =>
or case u @ IsUpperCase(_) =>
, which means "match IsUpperCase(v)
and if it succeeds bind the original string to u
".
来源:https://stackoverflow.com/questions/11284048/scala-pattern-matching-variable-binding