Синтаксис scala очень многообещающий. Я думал, что изначально scala - это больше, чем просто удобная java, и может ввести совершенно новую парадигму программирования, но многие функции, допускаемые синтаксисом, неверны с точки зрения семантики. Итак, я начал поиски ограничений scala и способов их устранения. Хотя я просто пишу тестовый проект, чтобы приспособить к 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)
Какое решение является лучшим из доступных? Введение нового признака является многословным (особенно для больших цепочек миксинов) и приводит к несовместимости типов. Добавление фиктивных неявных аргументов - тоже не лучшая идея, потому что это увеличивает накладные расходы.
Обновить:
Мне очень жаль, я задал не тот вопрос. Меня больше интересует природа описанной ошибки, а не способы ее решения. Где происходит стирание типа? Я не вижу универсальных шаблонов в коде, который считается источником стирания типов. Каков механизм поведения компилятора?
B3
вы не переопределяете методtypeMe
изB1
, а перегружаете его, чтобы он принял подтип. Хотя это законно, это плохая идея, поскольку вызываемый метод будет зависеть от типа локальной переменной. т.е. предполагая, что объектB3
b3
и объектT3
t3
,b3.typeMe(t3)
иb3.typeMe(t3: T1)
будут вызывать разные методы. - person Luigi Plinge   schedule 28.02.2012