我发现自己看了一些 Scalawags#2 的录音,然后是关于类型擦除的部分,Dick Wall 指出反射最终会咬你的脚。
所以我在想一些我经常做的事情(我也看到了 Scala Collections 的实现)。假设我有一个带有序列化程序的系统,将系统作为类型参数:
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
有难闻的气味。对这种方法有什么建议吗?让我补充两件事
- 将类型参数从 trait 的构造函数移动
Serializer
到read
方法不是一种选择(有特定的序列化程序需要参数化的值参数S
) - 向 的类型构造函数参数添加方差
Serializer
不是一种选择