Рассмотрим следующий пример:
object MatchDuckType {
trait Sup
class Sub1() extends Sup {
def v1: String = "a"
}
def example(v: Any) = {
v match {
case _: Sup { def v1: String } => println(1)
case _ => println(2)
}
}
def main(args: Array[String]): Unit = {
example(Sub1())
example(1)
}
}
Компилятор выдал следующую ошибку:
MatchDuckType.scala:16:12: the type test for xxx.MatchDuckType.Sup{v1: String} cannot be checked at runtime
Это утверждение явно неверно, так как Sup { def v1: String }
можно легко проверить с помощью отражения во время выполнения Java (сначала получив класс термина, а затем получив сигнатуры его методов). Почему предупреждение все еще существует? Это ошибка в компиляторе?
Вы можете включить -Xprint:typer
или -Xprint:jvm
в Scala 2 или -Xprint:typer
или -Xprint:genBCode
в Scala 3.
То, что это не работает, — это не просто «ошибка»; включение такой вещи в язык потребовало бы серьезной работы по проектированию, спецификации и реализации.
Функция, на которую вы надеялись, не существует ни в Scala 2, ни в Scala 3.
Я нашел запрос на эту функцию, датированный 2007 годом (!), но он никогда не привлекал особого внимания: https://github.com/scala/bug/issues/329
Даже если бы эта функция существовала, она была бы специфичной для платформы и ограниченной по объему: она работала бы только на JVM, а не на JS или Native, и работала бы только для подмножества типов уточнения, которые могут быть достоверно представлены. в байткоде. Это упускает из виду большую часть системы типов Scala.
(По крайней мере, без TypeTag
, но TypeTag
предназначен только для Scala 2; запрос функции на сопоставление на основе TypeTag
: https://github.com/scala/bug/issues/6517. В контексте Scala 3 рассмотрите возможность попытки вместо этого использовать типы соответствия?)
Что касается вашего замечания о дешугаринге, шаблон сопоставляет desugar с isInstanceOf
, и поведение isInstanceOf
такое же, так что речь идет не о сопоставлении с образцом как таковом, а о тестах типов.
Хорошо, что после внедрения JS или Native отражение становится скорее минным полем, на которое нельзя полагаться. Мне нравится идея совмещения Typeable/TypeTag в байт-коде. Мне просто не нравится вызывать их определение в коде вручную :) Поскольку стирание типов происходит во многих языках. Было бы интересно увидеть исследования в области проверки среды выполнения "постепенно/по запросу".
Я чувствую, что Scala 3 нуждается в более систематическом подходе к сопоставлению с образцом, самый простой способ сделать это, вероятно, объяснить его эквивалентную форму без сахара как часть предупреждающего сообщения.