【问题标题】:Scala - refer child class in parent (generics)Scala - 在父类中引用子类(泛型)
【发布时间】:2023-04-02 01:02:02
【问题描述】:

在泛型的情况下,我试图在 trait 中引用子类。这可能是不可能的,但如果有人知道这个问题的解决方案,我会很高兴。更多信息在下面的示例中。


object TestMain {
  trait A {
    def doSomething(objects: Seq[A]): A // can I put something here instead of A to make it work?
  }
  case class B() extends A {
    override def doSomething(objects: Seq[B]): B = {
      objects.head
    }
  }
  case class C() extends A {
    override def doSomething(objects: Seq[C]): C = {
      objects.head
    }
  }

  def main(args: Array[String]): Unit = {
    B().doSomething(Seq(B(), B())) //ok
    C().doSomething(Seq(C(), C())) //ok
    B().doSomething(Seq(B(), C())) //I want compile time error
  }
}

我希望 A 和 B 类在编译时只接受它们自己的集合,而不是在每个类中进行检查。有可能吗?

【问题讨论】:

  • typeclass 比继承要好。看看this
  • 您也可以尝试使用this.type 而不是原始定义中的A 或F 有界多态性。看看this article

标签: scala generics


【解决方案1】:

正如@user 所说,您可以使用F-bounded polymorphism 来实现您想要的。

鉴于您的示例,我将 F-bounded 应用为:

object TestMain {
  trait A[Me <: A[Me]]{
    def doSomething(objects: Seq[Me]): A[Me] // can I put something here instead of A to make it work?
  }
  case class B() extends A[B] {
    override def doSomething(objects: Seq[B]): B = {
      objects.head
    }
  }
  case class C() extends A[C] {
    override def doSomething(objects: Seq[C]): C = {
      objects.head
    }
  }

  def main(args: Array[String]): Unit = {
    B().doSomething(Seq(B(), B())) //ok
    C().doSomething(Seq(C(), C())) //ok
    B().doSomething(Seq(B(), C())) //now this thrown a compile time error
  }
}

【讨论】:

  • 一个小问题 - 第 3 行必须更改为: def doSomething(objects: Seq[Me]): A[Me] 并且它有效。谢谢你的帮助:)
  • 对 :) 我尽快更改答案 :)
猜你喜欢
  • 2022-10-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-06-24
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-09-10
相关资源
最近更新 更多