在 Scala 的模式匹配系统中使用比较运算符

有没有可能用 Scala 的模式匹配系统进行比对? 例如:

a match {
case 10 => println("ten")
case _ > 10 => println("greater than ten")
case _ => println("less than ten")
}

第二个 case 语句是非法的,但是我希望能够指定“ when a is more than”。

80891 次浏览

您可以在模式后面添加一个约束,即 if和一个布尔表达式:

a match {
case 10 => println("ten")
case x if x > 10 => println("greater than ten")
case _ => println("less than ten")
}

编辑: 请注意,这与把 if 之后放在 =>上表面上是完全不同的,因为如果保护不真实,模式 不会就会匹配。

作为对这个问题精神的非回答,这个问题要求如何将谓词合并到一个匹配子句中,在这种情况下,谓词可以在 match之前被分解出来:

def assess(n: Int) {
println(
n compare 10 match {
case 0 => "ten"
case 1 => "greater than ten"
case -1 => "less than ten"
})
}

现在,scala.math.Ordering.compare(T, T)的文件只承诺不相等的结果将是 大于小于零。Java 的 Comparable#compareTo(T)的指定类似于 Scala 的。正负值分别使用1和 -1是常规做法,正如 Scala 的 目前的实施情况所做的那样,但是我们不能做出这样的假设,否则实现会有从底层发生变化的风险。

在我看来,这个解决方案比增加警卫更容易理解:

(n compare 10).signum match {
case -1 => "less than ten"
case  0 => "ten"
case  1 => "greater than ten"
}

备注:

虽然上面和下面的答案完美地回答了原来的问题,一些额外的信息可以在文档 https://docs.scala-lang.org/tour/pattern-matching.html中找到,他们不适合我的情况,但是因为这个堆栈溢出的答案是第一个建议在谷歌我想张贴我的答案,这是一个角落的情况下的问题上面。
我的问题是:

  • 如何在匹配表达式中使用带参数的守护符 功能

可以这样解释:

  • 如何在匹配表达式中使用 if 语句和 功能

答案是下面的代码示例:

    def drop[A](l: List[A], n: Int): List[A] = l match {
case Nil => sys.error("drop on empty list")
case xs if n <= 0 => xs
case _ :: xs => drop(xs, n-1)
}

链接到 scala fiddle: < a href = “ https://scalafiddle.io/sf/G37THif/2”rel = “ nofollow norefrer”> https://scalafiddle.io/sf/g37thif/2 正如您所看到的,case xs if n <= 0 => xs语句能够将 n (函数的参数)与 Guard (if)语句一起使用。

我希望这能帮到像我这样的人。

Scala 的模式匹配允许你定义自己的提取器。 在这种情况下,您可以简单地定义一个新的提取器:

class GreaterThan(n: Int) {
def unapply(i: Int) = i > n
}


val GreaterThan10 = GreaterThan(10)


a match {
case 10 => ???
case GreaterThan10() => ???
case _ => ???
}

或者干脆用防护罩。