Я поймал себя на том, что смотрю отрывок из записи Scalawags#2, а затем идет эта часть о стирании шрифта и Дике Уолле, указывающем, что отражение в конце концов укусит вас за ноги.
Итак, я подумал о чем-то, что я делаю довольно часто (и я также видел реализацию коллекций Scala). Допустим, у меня есть система с сериализатором, принимающим систему в качестве параметра типа:
trait Sys[S <: Sys[S]] { type Tx }
trait FooSys extends Sys[FooSys]
trait Serializer[S <: Sys[S], A] {
def read(implicit tx: S#Tx): A
}
Теперь существует много типов A
, для которых сериализаторы могут быть созданы без параметров-значений, поэтому, по сути, параметр системного типа является "пустым". И поскольку сериализаторы в моем примере активно вызываются, я сохраняю инстанцирование:
object Test {
def serializer[S <: Sys[S]] : Serializer[S, Test[S]] =
anySer.asInstanceOf[Ser[S]]
private val anySer = new Ser[FooSys]
private final class Ser[S <: Sys[S]] extends Serializer[S, Test[S]] {
def read(implicit tx: S#Tx) = new Test[S] {} // (shortened for the example)
}
}
trait Test[S <: Sys[S]]
Я знаю, что это правильно, но, конечно, asInstanceOf
имеет неприятный запах. Есть ли какие-либо предложения по этому подходу? Позвольте мне добавить две вещи.
- перемещение параметра типа из конструктора типажа
Serializer
в методread
не является вариантом (существуют специальные сериализаторы, для которых требуются аргументы-значения, параметризованные вS
) - добавление дисперсии к параметру конструктора типа
Serializer
не вариант