Синтаксис scala очень многообещающий. Первоначально я думал, что scala - это больше, чем просто удобная java, и он может вводить совершенно новую парадигму программирования, но многие возможности, допускаемые синтаксисом, неверны в семантике. Поэтому я начал поиски ограничений для scala и хаков для их устранения. Хотя я просто пишу тестовый проект, чтобы приспособиться к способам и моделям скала с другой точки зрения.
Основным препятствием является стирание типа, унаследованное от реализации jvm. Я могу написать небольшую статью под названием «Десять красивых шаблонов, которые уничтожило стирание шрифтов». Говорят, что стирание типов портит дженерики, но я наткнулся на стирание типов в миксинах. Я считаю это проблемой с реализацией миксина в scala.
Преамбула
trait T1
trait T2
trait B1 {
def typeMe(x:T1){}
}
Сломанный код с миксинами
trait B2 extends B1 {
def typeMe(x:T1 with T2) {}
}
Рабочий код с миксином, объявленным как отдельная черта
trait T3 extends T1 with T2
trait B3 extends B1 {
def typeMe(x:T3) {}
}
Ошибка:
error: name clash between defined and inherited member:
method typeMe:(x: T1 with T2)Unit and
method typeMe:(x: T1)Unit in trait B1
have same type after erasure: (x: $line12.$read#$iw#$iw#T1)Unit
def typeMe(x:T1 with T2)
Какой лучший обходной путь доступен? Введение новой черты является многословным (особенно для больших цепочек миксинов) и приводит к несовместимости типов. Добавление фиктивных неявных аргументов также не является серебряной пулей, поскольку увеличивает накладные расходы.
обновление:
Мне очень жаль, я задал неправильный вопрос. Меня больше интересует природа описанной ошибки, а не ее обходные пути. Где происходит стирание типа? Я не вижу обобщений в коде, который считается источником стирания типа. Какая механика стоит за поведением компилятора?