Scala中非案例类的模式匹配

Eug*_*Loy 7 scala pattern-matching

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

class Price(var value: Int)
Run Code Online (Sandbox Code Playgroud)

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

例如,我想实现功能:

def printPrice(price: Price) = {
    // implementation here
}
Run Code Online (Sandbox Code Playgroud)

...打印price is {some value}每个pricevalue <= 9000price is over 9000所有其他情况.

例如,调用:

printPrice(new Price(10))
printPrice(new Price(9001))
Run Code Online (Sandbox Code Playgroud)

应该打印:

price is 10
price is over 9000
Run Code Online (Sandbox Code Playgroud)

如何printPrice使用模式匹配实现?

Ser*_*nko 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))
Run Code Online (Sandbox Code Playgroud)

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

  • 提取器不限于伴随对象.你可以在任何地方定义它.我更新了我的答案. (2认同)

Eug*_*Loy 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")
}
Run Code Online (Sandbox Code Playgroud)

PS:归功于 Flavian 展示了您可以if在模式中使用。对此你的答案表示赞同。

  • 好吧,谈论模式匹配的细节,[你也可以类级别或](http://stackoverflow.com/a/15656032/298389) (2认同)