繁体   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