2010-02-02 14 views
13

Mã sau đây cố gắng bắt chước Polymorphic Embedding of DSLs: thay vì đưa ra hành vi trong Inner, nó được mã hóa theo phương pháp useInner của lớp kèm theo của nó. Tôi đã thêm phương thức enclosing để người dùng chỉ có thể tham chiếu đến Inner trường hợp, nhưng luôn có thể có được trường hợp kèm theo của họ. Bằng cách này, tất cả các cá thể Inner từ một cá thể Outer cụ thể chỉ được gắn với một hành vi (nhưng nó được yêu cầu ở đây).Đề cập đến loại của một lớp bên trong trong 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) 

Nó không biên dịch và scala 2,8 phàn nàn về:

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

Từ Programming Scala: Nested classesA Tour of Scala: Inner Classes, có vẻ như với tôi rằng vấn đề là useInner hy vọng như là đối số một Inner dụ từ một Outer dụ cụ thể .

Giải thích thực sự là gì và cách giải quyết vấn đề này?

Trả lời

16

Tôi cho rằng loại Nội bộ giống như loại này.Inner. Outer # Inner độc lập với thể hiện bên ngoài (không phải kiểu phụ thuộc đường dẫn).

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

Có thể thế nào để sửa đổi toBoolean thay vì useInner? –

+0

Nếu cố gắng 'def toBoolean (x: y.Inner forSome {val y: Outer}): Boolean = x.enclosing.useInner (x)' (Các loại tồn tại - Định lượng tồn tại so với giá trị từ tham chiếu Scala) nhưng nó không công việc. –

4

Vấn đề là như bạn mô tả, mà useInner được mong đợi một Inner của một Outer dụ cụ thể. Vì enclosing trả về một số chung là Outer, thực sự không có cách nào để kết hợp cả hai với nhau mà tôi biết.

Bạn có thể buộc nó, tuy nhiên:

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

Bạn cũng có thể xác định thành viên của bạn như thế này:

def useInner(x:Outer#Inner) : Boolean 

Hoặc bạn có thể viết như thế này:

abstract class Outer { 
    class InnerImpl { 
     def enclosing = Outer.this 
    } 
    final type Inner = Outer#InnerImpl 
    def useInner(x:Inner) : Boolean 
} 
Các vấn đề liên quan