2010-02-02 51 views
13

下面的代碼嘗試模仿Polymorphic Embedding of DSLs:而不是在Inner中給出行爲,它將在其封閉類的useInner方法中進行編碼。我添加了enclosing方法,以便用戶只需保留對Inner實例的引用,但始終可以獲取其封閉實例。通過這樣做,來自特定Outer實例的所有Inner實例都只能綁定一個行爲(但在此需要)。引用Scala中的內部類的類型

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預計作爲參數從特定Outer例如一個Inner實例。

什麼是真正的解釋和如何解決這個問題?

回答

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) 
+0

是否有可能修改toBoolean而不是useInner? – 2010-02-02 13:11:21

+0

如果嘗試'def toBoolean(x:y.Inner forSome {val y:Outer}):Boolean = x.enclosing.useInner(x)'(存在類型 - 來自Scala參考的存在量化值)但它沒有工作。 – 2010-02-02 13:36:16

4

的問題是,你形容,那useInner期待一個特定Outer實例的Inner。由於enclosing返回一個通用的Outer,所以我確實沒有辦法將兩者結合在一起。

您可以強制它,但是:

def toBoolean(x: Outer#Inner): Boolean = { 
    val outer = x.enclosing 
    outer.useInner(x.asInstanceOf[outer.Inner]) 
} 
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 
}