我想用一个子类参数化一个类型。请考虑以下事项:
class DataLoader {
class Data { /* data specifics to this data loader */ }
def getData : Data /* and so on */
}
现在我想让这个加载器能够异步地从网络中检索数据。其中一个选项是让它成为Callable的子类。
class DataLoader extends Callable[Data] {
class Data { /* ... */ }
def call : Data = { ... }
}
val futureData = executor.submit(new DataLoader)
futureData.get
Scala不会让我这样做,因为当我提供Callable的参数时,数据还不知道。如果我写DataLoader.Data,Scala会给我一个循环引用。
当然,我可以在我的加载器之外编写我的数据类,但有些情况下内部更好。当然,另一个替代方案是拥有一个DataManager,其中包含一个Data类型和一个扩展Callable [Data]的Loader - 在这种情况下可以说是更好的设计。但是除了这些问题之外,有没有什么方法可以实际实现一个特性,包括编写一个返回T的函数,将T设置为内部类?
答案 0 :(得分:4)
有一百万种方法可以达到合理的效果,因此很难知道如何回答。我认为你不想过于依赖于在一个子类型自己的内部类中参数化超类型的想法。即使它有效,也不会。
在我随机挑选内容的百万种方式中,结果是涉及倒置。我是这样做的,因为你在评论中说你无法在同伴对象中编译它,我不知道为什么会这样。
import java.util.concurrent.Callable
class DataLoader extends Callable[DataLoader.Data] {
def call = new DataLoader.Data(this)
}
object DataLoader {
private class Data(loader: DataLoader) {
}
}
答案 1 :(得分:2)
这个怎么样?
trait Callable {
type TData
def getData: TData
}
class DataLoader extends Callable {
type TData = Data
class Data
override def getData: TData = new Data
}
修改强>
抱歉,没有注意到你的意思是来自java.util.concurrent的Callable ..然后添加以下内容可能有所帮助:
implicit def c2c[T](c: Callable {type TData = T}) = new java.util.concurrent.Callable[T] {
def call = c.getData
}
答案 2 :(得分:2)
将该类放在对象伴随文件中。