Я просто написал эту функцию, гадая, что произойдет, если я пропущу регистр Nil, и заметил, что scalac выдает предупреждение:
def printList[String](list: List[String]) {
list match {
case head :: tail => {
println(head)
printList(tail)
}
//case Nil => println("Done")
}
}
Warning: match may not be exhaustive.
It would fail on the following input: Nil
У меня проблемы с точным определением того, что здесь происходит. Я получаю общее представление о сопоставлении с образцом в рекурсивном типе данных, пока вы не исчерпываете все случаи, но мне не ясно, как это соотносится с системой типов Scala. В частности, я смотрю на исходный код стандартной библиотеки Scala и задаюсь вопросом:
- Где именно в коде Scala понимает, что для выполнения оператора соответствия для экземпляра класса List требуется базовый случай? Конечно, можно представить себе алгебраический тип данных, который «просто продолжает работать» без базового случая.
- Где именно в коде scala.collection.immutable.Nil, в частности, обозначен как базовый вариант для класса List?
Nil
речь идет не о базовом случае.List
запечатан, поэтому компилятор знает, какие типы искать в совпадении, а именно::
иNil
. Когда один из них отсутствует, это довольно хороший намек на то, что это не исчерпывающий матч. - person Michael Zajac   schedule 05.05.2015