让我们假设我有一个简单的第三方(即我不能修改它)类定义如下:
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
?
答案 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
魔法。