类型类型必需但C找到

时间:2015-08-08 16:13:37

标签: scala

我已经查看过已经提出的许多问题,但是没有一个问题能够解决或者似乎与我所遇到的问题相符。

这是我的抽象类:

abstract class GuiPowerBase[C <: Container](tile: TileBankBase, player: InventoryPlayer, width: Int, height: Int, name: String)
                                    extends GuiBase[C](new C(player, tile), width, height, name) {

这是GuiBase类:

abstract class GuiBase[T <: Container](val inventory : T, width : Int, height: Int, name : String)
    extends GuiContainer(inventory) with INEIGuiHandler {

这是GuiPowerBase的一个原因:

class GuiSolidsBank(player: InventoryPlayer, tileEntity: TileBankSolids)
    extends GuiPowerBase[ContainerSolidsBank](tileEntity, player, 175, 165, "inventory.solidspower.title") {

我所看到的一切,似乎我需要一个ClassTag,或者也许是一个Manifest,但我尝试的一切似乎都不起作用。这甚至可能吗?

1 个答案:

答案 0 :(得分:3)

您看到此错误的原因如下:

extends GuiBase[C](new C(player, tile), width, height, name)

在Scala和Java中,类型变量在执行期间被删除,因此在运行时没有关于C类型变量的信息,除非您没有使用反射来获取此信息运行。尽管这样做是可行的,但我个人不喜欢它支持类型类方法,它给了我们临时的多方性。这是类型类的方法:

trait ContainerBuilder[C <: Container] {
  def build(title: TileBankBase, player: InventoryPlayer): C
}

object ContainerBuilder {
  def apply[C <: Container: ContainerBuilder]: ContainerBuilder[C] = implicitly[ContainerBuilder[C]]

  implicit val containerSolidsBank: ContainerBuilder[ContainerSolidsBank] = {
    new ContainerBuilder[ContainerSolidsBank] {
      def build(title: TileBankBase, player: InventoryPlayer): ContainerSolidsBank = ???
    }
  }
}

abstract class GuiPowerBase[C <: Container: ContainerBuilder](tile: TileBankBase, player: InventoryPlayer, width: Int, height: Int, name: String)
  extends GuiBase[C](ContainerBuilder[C].build(player, tile), width, height, name)

使用这种方法可以帮助您避免反思。当然,它对你的特定情况来说太具体了,但是没有人阻止你使它变得更普遍,例如依赖类型。