2010-02-02 24 views
13

Aşağıdaki kod, Inner davranışını vermek yerine, useInner kapsayıcı sınıfının yönteminde kodlanmış olmak yerine, Polymorphic Embedding of DSLs taklit etmeye çalışır. enclosing yöntemini ekledim, böylece kullanıcının yalnızca Inner örneklerine bir başvuru tutması gerekiyordu, ancak bunların her zaman kendi kapalı örneğini alabilirler. Bunu yaparak, belirli bir Outer örneğinden alınan tüm Inner örneklerinin yalnızca bir davranışı vardır (ancak burada istenir).Scala'da bir iç sınıf türüne gönderme

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) 

O derleme değil ve scala 2.8 şikayetçi: Programming Scala: Nested classes ve A Tour of Scala: Inner Classes itibaren

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

, sorun olduğunu bana öyle geliyor ki argüman olarak useInner beklediği belirli Outer örneğinden bir Inner örneği .

Bu açıklamanın anlamı nedir ve bu sorunun nasıl çözüleceği nedir?

cevap

16

İçerdekinin türü bu tür gibi olduğunu varsayalım. Dış # İç dışsal durumdan bağımsızdır (yola bağımlı tipte değil). açıkladığınız olarak

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

mümkün mü useInner yerine toBoolean değiştirmek için? –

+0

Eğer "defol" için deneniyorsa (x: y.Inner forSome {val y: Outer}): Boolean = x.enclosing.useInner (x) '(Varoluşsal Türler - Scala referansından Değerler Üzerinden Varoluşsal Niceleme) iş. –

4

sorun olduğunu useInner belirli Outer örneğinin bir Inner bekliyor vardır. enclosing, bir genel Outer döndürdüğünden, bildiğim kadarıyla birlikte bağlamanın hiçbir yolu yoktur.

Bununla birlikte, zorlayabilirsiniz:

def useInner(x:Outer#Inner) : Boolean 

Ya da bunun gibi yazabilirsiniz:

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

Ayrıca bu gibi üye tanımlayabilirsiniz

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