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

Bef*_*rem 147 scala pattern-matching

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

a match {
    case 10 => println("ten")
    case _ > 10 => println("greater than ten")
    case _ => println("less than ten")
}
Run Code Online (Sandbox Code Playgroud)

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

Ben*_*mes 283

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

a match {
    case 10 => println("ten")
    case x if x > 10 => println("greater than ten")
    case _ => println("less than ten")
}
Run Code Online (Sandbox Code Playgroud)

编辑:请注意,这与表面if 之后的表面不同=>,因为如果防护不是真的话,模式将不匹配.

  • Ben,很好的答案,它确实说明了模式保护的重要性. (2认同)

seh*_*seh 32

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

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

现在,承诺的文件scala.math.Ordering.compare(T, T)只是非平等结果将大于小于零.Java的Comparable#compareTo(T)指定与Scala类似.正如Scala 当前的实现所做的那样,分别使用1和-1作为正值和负值恰好是常规的,但是如果没有实现从下面改变的风险,就不能做出这样的假设.

  • 我不确定你是否认为这是一个真正的解决方案,但我强烈建议不要依赖于无证的惯例或假设. (5认同)
  • Math.signum(n比较10)将保证-1,0或1. (4认同)
  • 一个有效的答案,但是我个人不喜欢这样。忘记0,1和-1应该意味着什么太容易了。 (2认同)

ver*_*nzt 19

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

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

笔记:

  • Ordered.compare如果小于该值则返回负整数,如果更大则返回正数, 0如果相等则返回.
  • Int.signum压缩从输出compare-1用于负数(小于10),1用于正(大于10),或0零(等于10).