【问题标题】:How to group parameterized types (classes)?如何对参数化类型(类)进行分组?
【发布时间】:2013-06-16 23:09:02
【问题描述】:

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

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 ...
  }

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

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

【问题讨论】:

    标签: scala generics types parameterized-types


    【解决方案1】:

    我总是称这种构造为“表示”类型,但也许这不是正式名称(您可能听说过“F-bounded quantification”一词)。您的类型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 =&gt;self: R =&gt;

    有了这些,它就可以编译了,你不能创建一个不满足约束的非抽象子类。

    【讨论】:

    • 我已经实现了,而且效果很好。因此,如果在“跨类”方法调用中使用this,则需要自键入来实现this 的类型相等?而且 - 再次 - 非常感谢。
    • self 类型表示,您保证最终类将属于该类型。因此,当您调用getTable.insert(this) 时,编译器知道this 不仅仅是RowBuffer 的某个子类型,而且确实是B,这是insert 方法所必需的。您通过其类型参数B 引入RowBuffer 的细化来打开的自我类型“关闭循环”。
    猜你喜欢
    • 2017-05-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多