簡體   English   中英

在 Scala 中使用匿名 class 中的類型參數

[英]Using type parameter in anonymous class in Scala

我正在嘗試在匿名 class 中聲明參數化類型的屬性。 這適用於 Java,在 Scala (2.9) 但是我得到編譯錯誤:

Parameter type in structural refinement may not refer to an abstract type defined outside that refinement

這是代碼:

object DemoFail extends App {
  def it[T <: AnyRef](x: T) = new Iterator[T] {
    var i = x // here is the error
    def next = i
    def hasNext = true
  }
  for (i ← it(int2Integer(4))) println(i)
}

我可以通過手動“擦除”類型來使其工作:

object DemoOK extends App {
  def it[T <: AnyRef](x: T) = new Iterator[T] {
    var i: AnyRef = x
    def next = i.asInstanceOf[T]
    def hasNext = true
  }
  for (i ← it(int2Integer(4))) println(i)
}

所以問題是:為什么編譯器不能為我做呢?

一個快速的解決方法是避免結構返回類型:

object DemoFail extends App {
  // The same with an explicit (non structural) return type
  //                       vvvvvvvvvvvvv
  def it[T <: AnyRef](x: T): Iterator[T] = 
    new Iterator[T] {
      var i = x // no more error
      def next = i
      def hasNext = true
    }
  for (i ← it(int2Integer(4))) println(i)
}

實際上,在 object DemoFail上的方法沒有it的返回類型。 因此,此返回類型由編譯器推斷。

在這里,當您覆蓋現有成員並向Iterator[T]添加新成員時,該it的推斷返回類型是Iterator[T] with Object {def next: T; var i: T; def hasNext: Boolean} Iterator[T] with Object {def next: T; var i: T; def hasNext: Boolean} Iterator[T] with Object {def next: T; var i: T; def hasNext: Boolean} (就像 IntelliJ 可以建議的 IDE 一樣)。

因此,您正在定義一個方法,其返回類型是使用同一方法的抽象類型的結構類型。 這就是困擾 scalac(具有相同方法的抽象類型的結構類型)的問題。

不幸的是,我不確定為什么這不起作用。 但這是避免強制轉換的替代解決方法:

def it[T <: AnyRef](x: T) = {
  class Forever extends Iterator[T] {
    var i = x
    def next = i
    def hasNext = true
  }
  new Forever
}

通過向迭代器添加公共變量,您可以創建一個結構類型,它是迭代器的子類型。 如果您將 i 更改為私有變量,它將起作用。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM