Scala: есть ли возможность использовать такие термины, как (x + 1), в качестве параметров для сопоставления с образцом класса дел? - PullRequest
0 голосов
/ 04 мая 2020

Предположим следующую ситуацию

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 x == x0+1 и просто написать

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

К сожалению это не компилируется - но есть ли способ достичь чего-то подобного?

Ответы [ 2 ]

1 голос
/ 04 мая 2020

Вы можете выполнить эту работу, если определите объект экстрактора

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
}

Вы не можете восстановить оба слагаемых из значения суммы.

Еще один вариант -

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
}

Честно говоря, я не знаю не думаю, что оно того стоит.

1 голос
/ 04 мая 2020

Ну, вы можете просто case MyCaseClass(18) или, если вам действительно нужно сделать арифметику c, вы можете:

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