我想做什么:
trait BasicModel {
type U <: BasicModel
def -(that: U): BasicModel
...
}
class MatrixFactorizationModel(val W: DenseMatrix[Double], val b: Double) extends BasicModel {
type U = MatrixFactorizationModel
def -(that: MatrixFactorizationModel): MatrixFactorizationModel = new MatrixFactorizationModel(W + that.W, b - that.b)
...
}
abstract class SAG [T <: BasicModel#U : ClassTag] {
//type T <: BasicModel#U I also tried like that
def modelDerivative(idx: Index, cstDerivative: Double): T
def compute(): T = {
SumDerivative = SumDerivative - modelDerivative(idx, Hist(idx))
}
}
当调用compute时,我收到了这个错误:
type mismatch;
found : T
required: _129.U where val _129: T
SumDerivative = SumDerivative - modelDerivative(idx, Hist(idx))
我不明白为什么这不起作用,因为T是BasicModel #U。有人可以解释我,给我一个替代方案吗?
编辑:
我在T&lt;:BasicModel中更改了SAG T&lt;:BasicModel #u,当我使用T在T#U中更改它时:
abstract class SAG [T <: BasicModel : ClassTag] extends Optimizer {
def modelDerivative(idx: Index, cstDerivative: Double): T#U
...
}
但是:
type mismatch;
found : T#U
required: _128.U where val _128: T#U
SumDerivative = SumDerivative - modelDerivative(idx, Hist(idx))
答案 0 :(得分:1)
它类似于BasicModel中定义的类型,U是BasicModel实例的成员。它类似于Java中静态/实例变量之间的区别。要匹配类型定义,您需要完全相同的类型。如果它是静态的,你就无法在子类MatrixFactorizationModel中覆盖它。
SAG中的 T <: BasicModel
表示任何 T&lt;:BasicModel#U(父#U),其中#U可以是BasicModel的任何子类型。即使您在实例化SAG实例的任何地方都可能碰巧指定了MatrixFactorizationModel,但编译器并不知道您在此上下文中具有哪些特定T,或者它是同一U的子类型。
你可能会有更好的运气trait BasicModel { def [T<:BasicModel]-(that:T):T }
。它有点冗长,如果您有很多方法签名要输入,可能会非常痛苦,但有时这样的签名效果更好。