Scala模式匹配变量绑定

时间:2012-07-01 17:10:15

标签: scala extractor

为什么在提取器返回Option[<Type>]时无法在@ -style中绑定变量?即这个不起作用:

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 _ => 
}

但是这个有效!

val s = "DuDu@qwadasd.ru"
s match {
  case IsUpperCase(u) => println("gotcha!")
  case _ => 
}

另一方面,如果IsUpperCase看起来像这样:

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

然后第一个例子起作用,第二个例子不起作用!为什么会这样?

2 个答案:

答案 0 :(得分:8)

  

什么? “对象IsUpperCase的参数数量错误”?

case u @ IsUpperCase() => println("gotcha!")

嗯,是的。 unapply的返回类型为Option[String],这意味着IsUpperCase 的模式匹配必须接受参数,如下所示:

case u @ IsUpperCase(_) => println("gotcha!") // I don't care about the parameter

符合第一种模式的unapply定义是:

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

可用于模式匹配IsUpperCase()

答案 1 :(得分:5)

因为对于第一个示例,您需要编写类似case u @ IsUpperCase(v) =>case u @ IsUpperCase(_) =>的内容,这意味着“匹配IsUpperCase(v),如果成功,则绑定原始字符串到u“。