我们假设我有一个像这样的通用类型:
class GenericEchoer[T <: Any] {
var content: T = _
def echo: String = "Echo: " + content.toString
}
然后可以创建一个mixin,它可以像这样扩展GenericEchoer [T]的功能:
trait Substitution[T <: AnyRef] extends GenericEchoer[T] {
def substitute(newValue: T) = { content = newValue }
}
有了这些定义后,我可以用这种方式实例化类型:
val echoer = new GenericEchoer[Int] with Substitution[Int]
我的问题是:如何实现类似的功能,以便我可以在mixin中省略类型参数?换句话说,我希望能够使用以下行实例化相同的类型:
val echoer = new GenericEchoer[Int] with Substitution
然而,这不起作用,因为替换“不知道”基础类型参数。
答案 0 :(得分:2)
您的代码错误,甚至无法编译。
您的GenericEchoer
不能是class
,因为您的content
成员是抽象的,或者您应该使用默认值启用它:
class GenericEchoer[T <: AnyRef] {
var content: T = _
def echo: String = "Echo: " + T.toString
}
你不能写T.toString
,我猜你想要content.toString
。您无法将Int
传递给它,因为Int
已将AnyVal
作为其超类型,而T
的上限为AnyRef
。
self.content
中的{p> Substitution
也是非法的,您应该:
1)将self
作为自我类型:
trait Substitution[T <: AnyRef] extends GenericEchoer[T] { self =>
def substitute(newValue: T) = { self.content = newValue }
}
2)将其替换为this
3)离开{ content = newValue }
至于你的问题。不,这是不可能的。我建议您用class
替换trait
并使用抽象类型成员键入构造函数:
trait GenericEchoer {
type T <: AnyRef
var content: T = _
def echo: String = "Echo: " + content.toString
}
trait Substitution extends GenericEchoer {
def substitute(newValue: T) { content = newValue }
}
val enchoer = new GenericEchoer with Substitution { type T = String }
或更好
val enchoer = new GenericEchoer with Substitution {
type T = String
var content = "Hello" // either case it will be null
}