Синтаксис scala очень перспективен. Я думал, что первоначально scala - это больше, чем просто удобная Java и может ввести совершенно новую парадигму программирования, но многие функции, разрешенные синтаксисом, неверны в семантике. Поэтому я начал поиски поиска ограничений scala и хаки, чтобы их устранить. Хотя я просто пишу тестовый проект, чтобы приспособиться к способам и шаблонам scala с другой точки зрения.Когда происходит стирание типа типа?
Главным препятствием является стирание типа, унаследованное от реализации jvm. Я могу написать небольшую статью под названием «Десять красивых узоров, которые стирают стирание». Говорят, что стирание стирает дженерики, но я наткнулся на стирание стилей в mixins. Я рассматриваю проблему с реализацией mixin в scala.
Преамбула
trait T1
trait T2
trait B1 {
def typeMe(x:T1){}
}
Разбитый Код с Mixins
trait B2 extends B1 {
def typeMe(x:T1 with T2) {}
}
рабочего кода с Mixin объявлен как отдельный признак
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)
Какое лучшее обходное решение доступно? Представление нового признака - это словосочетание (особенно для больших цепей mixin) и приводит к несовместимости типов. Добавление ложных неявных аргументов также не является серебряной пулей, потому что это увеличивает накладные расходы.
обновление:
Мне очень жаль, я задал неправильный вопрос. Мне больше интересна природа описанной ошибки, а не ее обходные пути. Где происходит стирание типа? Я не вижу дженериков в коде, который считается типом источника стирания. Какова механика поведения компилятора?
Вы можете рассмотреть альтернативу перегруженным методам; назовите их по-разному или используйте шаблон typeclass. – Owen
Надеюсь, вы понимаете, что в 'B3' вы не переопределяете метод' typeMe' из 'B1', но перегружаете его, чтобы взять подтип. Хотя это законно, это плохая идея, так как вызванный метод будет зависеть от типа локальной переменной. т. е. при условии, что объект 'B3'' b3' и объект 'T3'' t3', 'b3.typeMe (t3)' и 'b3.typeMe (t3: T1)' будут вызывать разные методы. –