Scala中非案例类的模式匹配

时间:2013-11-17 14:41:01

标签: scala pattern-matching

让我们假设我有一个简单的第三方(即我不能修改它)类定义如下:

class Price(var value: Int)

是否可以将此类的实例与某些模式匹配?

例如,我想实现函数:

def printPrice(price: Price) = {
    // implementation here
}

...在所有其他情况下,为price is {some value}price的每个value <= 9000打印price is over 9000

例如,呼叫:

printPrice(new Price(10))
printPrice(new Price(9001))

应打印:

price is 10
price is over 9000

如何使用模式匹配实现printPrice

3 个答案:

答案 0 :(得分:16)

您可以创建自定义提取器:

package external {
    class Price(var value: Int)
}

object Price {
    def unapply(price: Price): Option[Int] = Some(price.value)
}

def printPrice(price: Price) = price match {
    case Price(v) if v <= 9000 => println(s"price is $v")
    case _ => println("price is over 9000")
}

printPrice(new Price(10))
printPrice(new Price(9001))

对于案例类编译器自动生成它。我认为在你的情况下,提取器是过度的,但它可能只是简化的样本。

答案 1 :(得分:4)

考虑接受黄油的解决方案,但我自己提出稍微好一些。

以下是如何实现printPrice(无需使用包装器对象和修改原始类):

def printPrice(price: Price) = price match {
    case p: Price if (p.value <= 9000) => println("price is " + p.value)
    case p: Price => println("price is over 9000")
}

PS:表示您可以在模式中使用if来表示对flavian的信任。提出你的答案。

答案 2 :(得分:3)

您可以使用PIMP我的库模式:

case class RichPrice(value: Int) {}
  implicit def priceToRichPrice(price: Price): RichPrice = RichPrice(price.value)

  def printPrice(x: RichPrice): Unit = {
    x match {
      case RichPrice(value) if (value <= 9000) => println("below 9000")
      case RichPrice(value) if (value > 9000) => println("over 9000")
      case _ => println("wtf")
    }
  }
println(printPrice(new Price(10)))
println(printPrice(new Price(9001)))

使用case class的目的是让Scala定义用于模式匹配的apply方法和unapply魔法。