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

时间:2009-10-18 16:48:23

标签: scala pattern-matching

是否可以使用Scala中的模式匹配系统进行比较? 例如:

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

第二个案例陈述是非法的,但我希望能够指定“当a大于”时。

4 个答案:

答案 0 :(得分:272)

你可以在模式之后添加一个守卫,即一个if和一个布尔表达式:

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

修改:请注意,这与if =>后的{{1}} 不同,因为模式不会匹配如果后卫不是真的。

答案 1 :(得分:31)

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

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

现在,the documentation for scala.math.Ordering.compare(T, T)只承诺不相等的结果大于小于零。 Java Comparable#compareTo(T)的指定与Scala类似。正如Scala的current implementation所做的那样,分别使用1和-1作为正值和负值是常规的,但是如果没有实施从下面改变的风险,就不能做出这样的假设。 / p>

答案 2 :(得分:17)

在我看来,解决方案比添加警卫更具可读性:

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

注意:

  • Ordered.compare如果小于该值则返回负整数,如果更大则返回正数,并且 0如果相等。
  • Int.signum会将compare-1的输出压缩为负数(小于10),1为正数(大于10)或{{1}零(等于10)。

答案 3 :(得分:1)

尽管以上所有和下面的答案都能很好地回答原始问题,但可以在文档https://docs.scala-lang.org/tour/pattern-matching.html中找到一些其他信息,它们不适合我的情况,但是因为此stackoverflow答案是Google的第一个建议我想发表我的答案,这是上述问题的一个特例。
我的问题是:

  • 如何在带有参数a的匹配表达式中使用防护 功能?

可以这样解释:

  • 如何在带有参数a的匹配表达式中使用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)
    }

链接到斯卡拉小提琴:https://scalafiddle.io/sf/G37THif/2 如您所见,case xs if n <= 0 => xs语句能够将n(一个函数的参数)与guard(if)语句一起使用。

我希望这可以帮助像我这样的人。