Как использовать сопоставление с шаблоном без классов в Scala? - PullRequest
0 голосов
/ 02 декабря 2018

Я слышал, что мы можем применять сопоставление с образцом в Scala без использования case-классов.Кроме того, я имею в виду не просто определение фактического класса реализации, но также извлечение различных значений из объекта.Это действительно возможно?Как мы можем достичь этого?

Я не смог найти приемлемый ответ, который указывает на мое решение ни в одном из вопросов, опубликованных ранее по аналогичным темам.Поэтому я решил поставить новый вопрос.

Ответы [ 2 ]

0 голосов
/ 02 декабря 2018

Решения Arnon и Luis, объединенные для демонстрационных целей:

class A(val a: Int, val b: String, val c: Int)

// Handmade companion object for demonstration purpose only.
object A {
   def unapply(u: A): Option[(Int, String, Int)] =
    Some(u.a, u.b, u.c)
}

// No factory method found, so 'new' keyword is necessary.
val a = new A(1, "hello", 3)

/* With real case class the right side expression
    calls the unapply of the Object
   otherwise call must be explicitly.
*/
val Some((b, _, c)) = A.unapply(a)
// b: Int = 1
// c: Int = 3

def getId(user: A): Int = user match {
  case A(_, _, id) => id
}

getId(a) // 3
0 голосов
/ 02 декабря 2018

Классы дел не волшебны, то, что они делают под капотом, генерирует много шаблонного кода.
Между ними находятся apply (конструктор фабрики) и unapply (экстрактор) методов для сопутствующего объекта класса.
Когда вы пытаетесь сопоставить шаблон объекта, компилятор пытается вызвать метод экстрактора объекта-компаньона - таким образом, вам нужно всего лишь реализовать свой собственный объект экстрактора.

Например,

class User(val id: Int, val name: String)

object User {
  def apply(id: Int, name: String): User = new User(id, name)

  def unapply(user: User): Option[(Int, String)] =
    Some(user.id, user.name)
}

Теперь вы можете создать соответствие пользователей таким образом.

val user = User(3, "Luis")
def getId(user: User): Int = user match {
  case User(id, name) => id
}
getId(user) // 3

Для справки см. this .

...