【问题标题】:Scala: Is there a possibility to use terms like (x+1) as parameters for case class pattern matching?Scala:是否有可能使用 (x+1) 之类的术语作为案例类模式匹配的参数?
【发布时间】:2020-08-19 08:01:37
【问题描述】:

假设如下情况

case class MyCaseClass(x: Int) // some case clas with an Int parameter  

val x0 = 17 // some given Int value

val a = MyCaseClass(x=18) // a case class object

// using pattern matching to find out if *a* is of type MyCaseClass and its parameter x equals x0+1
a match {
    case MyCaseClass(x) if x == x0+1 => println("Found my case class with x==x0+1")
}

问题

如果可以跳过上面的 if 语句 if x == x0+1 并直接写

case MyCaseClass(x0+1) => println("Found my case class with x==x0+1")

不幸的是,这无法编译 - 但有什么方法可以实现这样的目标吗?

【问题讨论】:

    标签: scala pattern-matching parameter-passing case-class


    【解决方案1】:

    如果你定义了提取器对象,你就可以做到这一点

    object `+` {
      def unapply(x: Int): Option[(Int, Int)] = Some(x - 1, 1)
    }
    
    a match {
      case MyCaseClass(x0 + 1) => println(x0) // 17
    }
    

    这也行

    a match {
      case MyCaseClass(x0 + _) => println(x0) // 17
    }
    

    小心,使用不同的值会爆炸

    a match {
      case MyCaseClass(x0 + 2) => println(x0) // MatchError
    }
    

    您不能从 sum 的值恢复两个加法。

    还有一个选择是

    object `+1` {
      def unapply(x: Int): Option[Int] = Some(x - 1)
    }
    
    a match {
      case MyCaseClass(`+1`(x0)) => println(x0) // 17
    }
    

    object `+1` {
      def unapply(x: Int): Option[(Int, Int)] = Some(x - 1, 42)
    }
    
    a match {
      case MyCaseClass(x0 `+1` _) => println(x0) // 17
    }
    

    老实说,我认为这不值得。

    【讨论】:

      【解决方案2】:

      你可以case MyCaseClass(18) 或者如果你真的需要做算术,你可以:

      val x1 = x0 + 1
      a match {
        case MyCaseClass(`x1`) => ???
      }
      

      【讨论】:

      • 谢谢,但这似乎并不比 if 语句好。我想有一种方法可以使用像 x+1 这样的实数(!),而不是变量,作为案例类中的参数。
      • @FWE 这是不可能的。模式匹配检查模式,而不是术语。
      猜你喜欢
      • 1970-01-01
      • 2017-02-25
      • 1970-01-01
      • 2017-04-25
      • 2014-08-12
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-09-26
      相关资源
      最近更新 更多