Scala模式匹配:参数化的提取器对象可能吗?
是否可以创建可以使用的Extractor对象,例如:
val x = 42
x match {
case GreaterThan(80) => println("5")
case GreaterThan(70) => println("4")
case GreaterThan(60) => println("3")
case GreaterThan(40) => println("2")
case _ => println("1")
}
现在我知道使用if结构是可能的,但我觉得它混乱了我的代码(并且似乎是多余的: case MyMatcher(x) if MyCreteria(x) => _
),我想避免这种情况。
这是在使用提取物case
语句需要有一个unapply
方法。 不幸的是,由于对象本身是单身,所以没有办法(afaik)来创建这样的参数化对象。
在下面的代码中,我规避了这一点,即为每个限制创建特定的单例object
。
@ÁkosVandra:也许下面的代码是有帮助的(因为它最接近你的要求):
def main(args: Array[String]) : Unit = {
val n = 42
n match {
case GreaterThan50(x) => println("5")
case GreaterThan40(x) => println("4")
case GreaterThan30(x) => println("3")
case GreaterThan20(x) => println("2")
case _ => println("somewhat")
}
}
class GreaterThanLimit(val limit: Int) {
def unapply(x: Int): Option[Int] = if (x > limit) Some(x) else None
}
object GreaterThan10 extends GreaterThanLimit(10)
object GreaterThan20 extends GreaterThanLimit(20)
object GreaterThan30 extends GreaterThanLimit(30)
object GreaterThan40 extends GreaterThanLimit(40)
object GreaterThan50 extends GreaterThanLimit(50)
编辑2015-09-17
有了ÁkosVandra的意见,可以使用Boolean
代替Option[_]
并写入
def main(args: Array[String]) : Unit = {
val n = 42
n match {
case GreaterThan50() => println("5")
case GreaterThan40() => println("4")
case GreaterThan30() => println("3")
case GreaterThan20() => println("2")
case _ => println("somewhat")
}
}
class GreaterThanLimit(val limit: Int) {
def unapply(x: Int) : Boolean = x > limit
}
object GreaterThan10 extends GreaterThanLimit(10)
object GreaterThan20 extends GreaterThanLimit(20)
object GreaterThan30 extends GreaterThanLimit(30)
object GreaterThan40 extends GreaterThanLimit(40)
object GreaterThan50 extends GreaterThanLimit(50)
看来,滥用unapply
在你想将是非常棘手的(如果可能的话)的方式。 为什么你不想使用match
if
子句?
object GreaterThan {
def apply(x:Int, boundary:Int) = x > boundary
}
x match {
case x if GreaterThan(x, 80) => println("5")
case x if GreaterThan(x, 70) => println("4")
case _ => println("1")
}
它没有比原始代码冗长得多。
或者,你可以发明一些自定义模拟匹配:
class Matcher(val cond: Int => Boolean, command: => Unit) {
def evaluate() = command
}
val matchers = Seq(
new Matcher(_ > 80, {println("5")}),
new Matcher(_ > 70, {println("4")}),
new Matcher(_ > 60, {println("3")}),
new Matcher(_ > 40, {println("2")}),
new Matcher(_ => true, {println("2")})
)
val x = 42
matchers.find(_.cond(x)).foreach(_.evaluate())
但它更加冗长。
有什么理由不会这样做吗? 它不是特别冗长,并且为您节省了一些麻烦。
x match {
case _ if x > 80 => println("5")
case _ if x > 70 => println("4")
case _ if x > 60 => println("3")
case _ if x > 40 => println("2")
case _ => println("1")
}
链接地址: http://www.djcxy.com/p/29055.html
上一篇: Scala Pattern matching: Are parametrized extractor objects possible?
下一篇: Consuming message in the correct order from an Advanced Queue by Camel and JMS