在 Scala 泛型中实现字段 类

Implementing fields in Scala generic classes

我需要一些有关 Scala 中通用特征的帮助。

我有一个 class 方法 return 是类型 T。 在我的 class 的每个实现中,我想 return 一个可以使用的 T 的子class。

基本上,在我的摘要中 class 我需要一个方法 returning Configs 对象,每个实现都将有自己的 Configs 对象实现。 此外,我想用另一个抽象class subclass 抽象class,进一步限制这个Configs 对象(原始Configs 对象的sub-class)。无论我做什么,我都会遇到编译错误。

这是我试过的:

case class MyConfigs()

trait WithMyConfigs {
  def myConfigs: MyConfigs
}

case class LimitConfigs(myConfigs: MyConfigs, limit: Int) extends WithMyConfigs

case class TextConfigs(myConfigs: MyConfigs, text: String) extends WithMyConfigs


    trait AbstractClass {
      def configs[B <: WithMyConfigs]: B
    }

    class ImplLimitClass extends AbstractClass {
      override def configs[B <: WithMyConfigs]: B = LimitConfigs(MyConfigs(), 5)
    }

    class ImplSizeClass extends AbstractClass {
      override def configs[B <: WithMyConfigs]: B = TextConfigs(MyConfigs(), "test")
    }

    trait WithRestrictedConfigs extends WithMyConfigs {
      def additionalIntField: Int
    }

    trait RestrictedAbstractClass extends AbstractClass {
      override def configs[B <: WithRestrictedConfigs]: B
    }

    case class RestrictedConfigs(myConfigs: MyConfigs, additionalIntField: Int) extends WithRestrictedConfigs

    class ImplRestrictedClass extends RestrictedAbstractClass {
      override def configs[B <: WithRestrictedConfigs]: B = RestrictedConfigs(MyConfigs(), 5)
    }

有了这个,我得到错误“类型 TextConfigs/LimitConfigs 的表达式不符合预期的类型 B”。

我也试过以下方法:

case class MyConfigs()

trait WithMyConfigs {
  def myConfigs: MyConfigs
}

case class LimitConfigs(myConfigs: MyConfigs, limit: Int) extends WithMyConfigs

case class TextConfigs(myConfigs: MyConfigs, text: String) extends WithMyConfigs


trait AbstractClass {

  type B <: WithMyConfigs

  def configs: B
}

class ImplLimitClass extends AbstractClass {
  override def configs: B = LimitConfigs(MyConfigs(), 5)
}

class ImplSizeClass extends AbstractClass {
  override def configs: B = TextConfigs(MyConfigs(), "test")
}

trait WithRestrictedConfigs extends WithMyConfigs {
  def additionalIntField: Int
}

trait RestrictedAbstractClass extends AbstractClass {
  override type B <: WithRestrictedConfigs
  override def configs: B
}

case class RestrictedConfigs(myConfigs: MyConfigs, additionalIntField: Int) extends WithRestrictedConfigs

class ImplRestrictedClass extends RestrictedAbstractClass {
  override def configs: B = RestrictedConfigs(MyConfigs(), 5)
}

然后我得到“XXX 类型的表达式不符合预期类型 ImplRestrictedClass.this.B”。

如果有人知道如何提供帮助,那就太好了:)

您需要在您的实现中定义实际类型。看看 scala-doc.

下面是一个编译的例子:

case class MyConfigs()

trait WithMyConfigs {
  def myConfigs: MyConfigs
}

case class LimitConfigs(myConfigs: MyConfigs, limit: Int) extends WithMyConfigs

case class TextConfigs(myConfigs: MyConfigs, text: String) extends WithMyConfigs


trait AbstractClass {
  type T <: WithMyConfigs
  def configs :T
}

class ImplLimitClass extends AbstractClass {
  type T = LimitConfigs
  override def configs: T = LimitConfigs(MyConfigs(), 5)
}

class ImplSizeClass extends AbstractClass {
  type T = TextConfigs
  override def configs: T = TextConfigs(MyConfigs(), "test")
}

trait WithRestrictedConfigs extends WithMyConfigs {
  def additionalIntField: Int
}

trait RestrictedAbstractClass extends AbstractClass {
  type T <: WithRestrictedConfigs
  override def configs: T
}

case class RestrictedConfigs(myConfigs: MyConfigs, additionalIntField: Int) extends WithRestrictedConfigs

class ImplRestrictedClass extends RestrictedAbstractClass {
  type T = RestrictedConfigs
  override def configs: T = RestrictedConfigs(MyConfigs(), 5)
}

[更新]

您需要在某处指定您的类型。如果使用类型参数,你会得到类似的东西:

trait AbstractClass[T <: WithMyConfigs] {
  def configs: T
}

class ImplLimitClass extends AbstractClass[LimitConfigs] {
  override def configs = LimitConfigs(MyConfigs(), 5)
}

class ImplSizeClass extends AbstractClass[WithMyConfigs] {
  override def configs = TextConfigs(MyConfigs(), "test")
}

当然你可以指定特征本身以获得更通用的配置(参见上面的ImplSizeClass) 然后隐藏带有额外特征的类型参数。

trait SpecAbstractClass extends AbstractClass[WithMyConfigs]

如果您不想指定显式类型,为什么不使用老式的接口使用方式:

case class MyConfigs()

trait WithMyConfigs {
  def myConfigs: MyConfigs
}

case class LimitConfigs(myConfigs: MyConfigs, limit: Int) extends WithMyConfigs

case class TextConfigs(myConfigs: MyConfigs, text: String) extends WithMyConfigs


trait AbstractClass {
  def configs: WithMyConfigs
}

class ImplLimitClass extends AbstractClass {
  override def configs = LimitConfigs(MyConfigs(), 5)
}

class ImplSizeClass extends AbstractClass {
  override def configs = TextConfigs(MyConfigs(), "test")
}

trait WithRestrictedConfigs extends WithMyConfigs {
  def additionalIntField: Int
}

trait RestrictedAbstractClass extends AbstractClass {
  override def configs: WithRestrictedConfigs
}

case class RestrictedConfigs(myConfigs: MyConfigs, additionalIntField: Int) extends WithRestrictedConfigs

class ImplRestrictedClass extends RestrictedAbstractClass {
  override def configs = RestrictedConfigs(MyConfigs(), 5)
}