Фактически, тот факт, что :: является классом case, является только половиной ответа. Причина, по которой это работает в сопоставлении с образцом, заключается в том, что для объекта :: существует экстрактор, который генерируется автоматически при определении класса case. Удобно, ::. Unapply возвращает список, потому что :: extends List. Если вы хотите использовать тот же трюк для списков, вы не сможете расширить список, потому что это final. Что вы можете сделать, так это определить объект с соответствующим методом unapply, который имеет ожидаемую обратную подпись. Например, в соответствии с последним элементом списка, вы можете сделать:
object ::> {def unapply[A] (l: List[A]) = Some((l.init, l.last))}
List(1, 2, 3) match {
case _ ::> last => println(last)
}
(1 to 9).toList match {
case List(1, 2, 3, 4, 5, 6, 7, 8) ::> 9 => "woah!"
}
(1 to 9).toList match {
case List(1, 2, 3, 4, 5, 6, 7) ::> 8 ::> 9 => "w00t!"
}
экстрактора должен возвращать вариант, который содержит кортеж из двух деконструктивистских элементов.
Дубликат http://stackoverflow.com/questions/1059145/how-is-this-case-class-match-pattern-working, действительно. –
мой вопрос заключался не только в том, как получилось «::» между переменными, но и как класс case может соответствовать экземплярам другого класса (причина в том, что List # :: создает экземпляры класса case) – IttayD