Scala - 提取器无法应用混乱

时间:2012-06-28 05:31:13

标签: scala pattern-matching

我正在尝试编写一个提取器,用于匹配多参数案例类。简化示例:

case class X(p1: String, p2: Int)

我希望每个提取器对象为p1定义一个固定值,并在使用时定义p2。 (A,B等不能是case类和子类X,我也想用X()作为例子) 应用方法示例:

object A {
  def apply(p2: Int): X = X("A", p2)
}

object B {
  def apply(p2: Int): X = X("B", p2)
}

...

对于模式匹配,我希望它们匹配如下:

X("A", 2) match {
  case A(2) => true // <- should match: p1="A" and p2=2
  case A(_) => true // <- should match: p1="A" and p2=_
  case X("A", _) => true // <- should match: p1="A" and p2=_
  case A(1) => false // <- should not match
  case B(2) => false // <- should not match: p1="B" and p2=2
}

我知道我需要在unapplyA等中定义B方法,但我很清楚签名和逻辑应该是什么:

object A {
  def unapply(x: ???): Option[???] = {
    ???
  } 
}

请帮忙吗?

1 个答案:

答案 0 :(得分:14)

unapply获取Any并返回Option您要提取的任何内容。在你的情况下,这将是:

scala> case class X(p1: String, p2: Int)
defined class X

scala> object A {
     |   def unapply(target: Any): Option[Int] =
     |     PartialFunction.condOpt(target) {
     |       case X("A", p2) => p2
     |     }
     | }
defined module A

scala> val A(x) = X("A", 1)
x: Int = 1

scala> val A(x) = X("B", 1)
scala.MatchError: X(B,1) (of class X)
...

但说实话,您提出的示例可以在没有AB的情况下重写:

X("A",2) match {
  case X("A", 2) => true
  case X("A", 1) => false
  case X("A", _) => true
  case X("B", 2) => false
}