以下代码尝试模仿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 classes和A Tour of Scala: Inner Classes开始,我认为问题在于useInner
期望来自特定Inner
实例的Outer
实例作为参数。
真正的解释是什么以及如何解决这个问题?
答案 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
}