参考Scala中内部类的类型

时间:2010-02-02 12:31:00

标签: scala types inner-classes

以下代码尝试模仿Polymorphic Embedding of DSLs:它不是在Inner中提供行为,而是在其封闭类的useInner方法中进行编码。我添加了enclosing方法,以便用户只需保留对Inner实例的引用,但始终可以获取其封闭实例。通过这样做,来自特定Inner实例的所有Outer实例仅绑定到一个行为(但这里需要它)。

abstract class Outer {
  sealed class Inner {
    def enclosing = Outer.this
  }
 def useInner(x:Inner) : Boolean
}

def toBoolean(x:Outer#Inner) : Boolean = x.enclosing.useInner(x)

它没有编译和scala 2.8抱怨:

type mismatch; found: sandbox.Outer#Inner
               required: _81.Inner where val _81:sandbox.Outer

Programming Scala: Nested classesA Tour of Scala: Inner Classes开始,我认为问题在于useInner期望来自特定Inner实例的Outer实例作为参数。

真正的解释是什么以及如何解决这个问题?

3 个答案:

答案 0 :(得分:16)

我认为Inner类型就像this.Inner类型。 Outer#Inner独立于外部实例(不依赖于路径)。

abstract class Outer {
  sealed class Inner {
    def enclosing = Outer.this
  }
  def useInner(x:Outer#Inner) : Boolean
}

def toBoolean(x:Outer#Inner) : Boolean = x.enclosing.useInner(x)

答案 1 :(得分:4)

问题在于您所描述的,useInner期待特定Inner实例的Outer。由于enclosing会返回通用Outer,因此我无法将两者结合在一起。

但是你可以强制它:

def toBoolean(x: Outer#Inner): Boolean = {
  val outer = x.enclosing
  outer.useInner(x.asInstanceOf[outer.Inner])
}

答案 2 :(得分:0)

您还可以像这样定义您的成员:

def useInner(x:Outer#Inner) : Boolean

或者你可以这样写:

abstract class Outer {
    class InnerImpl {
        def enclosing = Outer.this
    }
    final type Inner = Outer#InnerImpl
    def useInner(x:Inner) : Boolean
}