【问题标题】:How can mixin know type parameters of generic superclassmixin如何知道泛型超类的类型参数
【发布时间】:2013-10-19 11:04:52
【问题描述】:

假设我有一个像这样的泛型类型:

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

但是,这不起作用,因为 Substitution“不知道”基础类型参数。

【问题讨论】:

  • 如果Substitution 扩展GenericEchoer 然后Susbstitution with GenericEchoer 扩展GenericEchoer 两次。你可能想解决这个问题。另外你为什么要限制T &lt;: AnyRef 类型然后尝试使用Int 这绝对不是AnyRef

标签: scala generics mixins


【解决方案1】:

你的代码是错误的,它甚至不会编译。

您的GenericEchoer 不能是class,因为您的content 成员是抽象的,或者您应该使用默认值来初始化它:

class GenericEchoer[T <: AnyRef] {
    var content: T = _
    def echo: String = "Echo: " + T.toString
}

你不能写T.toString,我猜你想要content.toString。你不能将Int 传递给它,因为IntAnyVal 作为它的超类型,而你的T 的上限是AnyRef

Substitution 中的self.content 也是非法的,你应该:

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
}

【讨论】:

  • 好的,我修正了你指出的错误。我还没有考虑过使用类型成员 - 谢谢。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-09-19
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多