Scala pattern matching variable binding

亡梦爱人 提交于 2019-12-24 14:36:00

问题


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

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!