14

下面的代码试图模仿DSLs 的多态嵌入:它没有给出 in 中的行为,而是在其封闭类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的实例作为参数。InnerOuter

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

4

3 回答 3

17

我想 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)
于 2010-02-02T12:55:27.137 回答
4

正如您所描述的,问题useInner是期望Inner一个特定的Outer实例。由于enclosing返回一个 generic Outer,我知道真的没有办法将两者联系在一起。

但是,您可以强制它:

def toBoolean(x: Outer#Inner): Boolean = {
  val outer = x.enclosing
  outer.useInner(x.asInstanceOf[outer.Inner])
}
于 2010-02-02T18:21:00.593 回答
1

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

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
}
于 2010-04-10T13:34:35.153 回答