Классы классов, сопоставления шаблонов и карьеры в Scala
Они, кажется, не смешивают это хорошо:
abstract class A
case class B (var a: Int)(var b: String) extends A
case class C extends A
Следующие действия не будут выполняться:
B(1)("1") match {
case B(a)(b) => print("B")
case C() => print("C")
}
Проблема заключается в том, что совпадение шаблонов и аргументы в валюте не работают. Для этого есть обход?
Ответы
Ответ 1
Что случилось с этим?
def m(a: A) = a match {
case b: B => print("B")
case c: C => print("C")
}
Я только спрашиваю, потому что вы не запрашивали больше функциональности, чем это.
ИЗМЕНИТЬ
Это может помочь:
object Dog {
def apply(name: String)(size: Int) = new Dog(name)(size)
def unapply(dog: Dog) = Some(dog.name, dog.size)
}
class Dog(val name: String)(var size: Int)
Теперь вы можете создавать собаки так:
new Dog("Snoopy")(10)
или вот так:
Dog("Snoopy")(10)
Но когда вы сопоставляете шаблоны с собаками, шаблон конструктора не карри.
Dog("Snoopy")(10) match {
case Dog(a, b) => // do sth with a or b
}
Ответ 2
Если вы посмотрите на подпись функции unapply, созданной для класса B, вы увидите, что это: unapply(x$0: Q): Option[Int]
. Таким образом, функция unapply работает с первым диапазоном параметров классов case.
Это подтверждается спецификацией scala (§5.3.2):
Формальные параметры в первом разделе параметров класса case называются элементами; они обрабатываются специально. Во-первых, значение такой параметр может быть извлечен как поле шаблона конструктора.
Он ясно заявляет, что через экстрактор доступен только первый раздел параметров.
Несколько обходных решений:
- удалить ваши параметры
- используйте сопоставление шаблонов с защитой, если вы хотите проверить 2 значения:
case [email protected](3) if x.b == "bazinga" => ...
- используйте обычный класс и определите свой собственный объект-компаньон со своим собственным apply/unapply
Ответ 3
Вы можете использовать обычный класс case и просто определить метод factory с более чем одним списком параметров.