如何对参数化类型(类)进行分组?

时间:2013-06-20 07:33:34

标签: scala generics types parameterized-types

鉴于三个属于一起的类(我试图通过类型参数来表达):

abstract class Row[T <: Table[T, R, B], 
                   R <: Row[T, R, B], 
                   B <: RowBuffer[T, R, B]] extends Immutable {
  def id: Int
  def getTable: T
  def toRowBuffer: B

  def delete() {
    // does not compile: Found Row.this.type ... Row[T, R, B], required: R
    getTable.delete(this)
  }
}

abstract class RowBuffer[T <: Table[T, R, B], 
                         R <: Row[T, R, B], 
                         B <: RowBuffer[T, R, B]] extends Mutable {
  def id: Int
  def getTable: T
  def toRow: R

  def insert(): R = {
    // does not compile: Found RowBuffer.this.type ... RowBuffer[T, R, B], 
    // required: B
    getTable.insert(this)
  }
}

abstract class Table[T <: Table[T, R, B], 
                     R <: Row[T, R, B], 
                     B <: RowBuffer[T, R, B]] {
  def insert(b: B): R = {
    // insert ...
    b.toRow
  }

  def delete(r: R) {
    // delete ...
  }

如果有“跨类”调用,我还没有设法定义正确的类型。 所以我的问题是:

  • 这个问题的名称是什么?
  • 如何以类型安全的方式表达它?

1 个答案:

答案 0 :(得分:3)

我总是将这种结构称为“表示”类型,但也许这不是官方名称(您可能会听到“F-有界量化”这一术语)。您的类型RowRowBuffer分别采用递归类型RB来描述最终实现的类型(“表示”)。

为了确保您可以填写抽象类的方法,您需要声明最终的实现将分别符合RB。您可以使用自我类型注释来执行此操作:

abstract class Row[T <: Table[T, R, B], 
                   R <: Row[T, R, B], 
                   B <: RowBuffer[T, R, B]] extends Immutable {
  _: R =>

  ...
}

abstract class RowBuffer[T <: Table[T, R, B], 
                         R <: Row[T, R, B], 
                         B <: RowBuffer[T, R, B]] extends Mutable {
  _: B =>

  ..
}

请注意,您可以使用任何标识符,例如this: R =>self: R =>

通过这些,它可以编译,并且您无法创建不满足约束条件的非抽象子类。