2011-08-31 27 views
5

Ví dụ:Lớp actuall cho định nghĩa cú pháp kiểu cấu trúc scala là gì?

type T = MyClass {def someMethod:String} 

Liệu nó có nghĩa để tạo trình biên dịch của đặc điểm như "trait AnonTrait extends MyClass {def someMethod:String}"? Hoặc nó được thực hiện thông qua cơ chế biên dịch khác? Câu hỏi của tôi là những gì thực sự bị ẩn bởi cú pháp Kiểu này.

Trả lời

3

Nó không ẩn tạo kiểu. Về cơ bản nó mặt nạ sử dụng sự phản chiếu để kiểm tra các ràng buộc cấu trúc của bạn tại thời gian biên dịch và để gọi someMethod khi chạy.

Ví dụ, nếu bạn có:

class Foo(t: MyClass {def someMethod:String}) { 
    def CallSomeMethod = t.someMethod 
} 

điều này có nghĩa các nhà xây dựng cho lớp Foo của bạn chấp nhận một t kiểu MyClass rằng cũng có một someMethod (nơi someMethod có thể được trộn vào MyClass qua một đặc điểm). Bạn có thể có:

class MyClass {} 
trait WithSomeMethod {def someMethod = "hello"} 

và sau đó bạn có thể tạo Foo như thế này:

val mc = new MyClass with WithSomeMethod 
val foo = new Foo(mc) 
println(foo.CallSomeMethod) // prints "hello" 

bây giờ, khi bạn tạo new Foo(mc) trình biên dịch sử dụng phản xạ để kiểm tra mc đó là một MyClass rằng cũng có một someMethod . Các cuộc gọi thực tế foo.CallSomeMethod hoạt động thông qua sự phản ánh là tốt.

Bây giờ (chịu với tôi, tôi nhận được cho câu hỏi thực tế của bạn ...) làm như bạn đã làm:

type T = MyClass {def someMethod:String} 

chỉ đang tạo ra một bí danh loại, không phải là một kiểu dữ liệu cụ. Khi bạn đã xác định T theo cách đó, bạn có thể xác định Foo là:

class Foo(t: T) { 
    def CallSomeMethod = t.someMethod 
} 

điều này tương đương với định nghĩa của Foo đã cho trước đó. Bạn vừa tạo một bí danh T có thể được sử dụng lại ở những nơi khác mà bạn có thể đã sử dụng MyClass {def someMethod:String}. Không có kiểu T thực tế nào được tạo ra và trình biên dịch vẫn sử dụng sự phản chiếu bất cứ khi nào bạn tham chiếu đến T, để kiểm tra ràng buộc cấu trúc mà nó có định nghĩa someMethod và vẫn tạo mã dựa trên sự phản chiếu để gọi someMethod.

+0

Cảm ơn, vì vậy việc sử dụng hạn chế về cấu trúc như chậm như phản ánh trong java? Và đặc điểm là lựa chọn tốt hơn trong những ánh sáng đó. – yura

+0

có, các loại kết cấu có tác động hiệu suất do phản ánh. –

3

Nó không tạo ra một Trait, nó chỉ là một bí danh loại có nghĩa là mỗi lần bạn tham khảo T, bạn tham khảo trong thực tế để MyClass {def someMethod:String}. Tuy nhiên, bạn có thể ghi đè khai báo loại bằng một đặc điểm:

trait A 

class B { 
    type T <: A 
} 

class SubB { 
    trait T extends A 
} 
+0

Câu hỏi của tôi là những gì thực sự bị ẩn theo cú pháp Loại này. – yura

+0

Câu trả lời của tôi là: bí danh loại. – Nicolas

3

Hãy xem xét điều này: một lớp không có loại cấu trúc. Loại của một lớp luôn là một lớp. Một đặc điểm tạo ra một giao diện. Một loại đối tượng đơn là một lớp học là tốt.

Và các loại cấu trúc xuất hiện ở đâu? Là loại để tham số và biến.

Ví dụ: tôi có thể nói def f(s: { def size: Int }) hoặc val r: { def close(): Unit }.

Bây giờ, các loại này xuất hiện như bytecode như thế nào? Giống như bất kỳ loại nào khác không được JVM hỗ trợ (chẳng hạn như Generics của Java), chúng được xóa.

Vì vậy, theo như mọi người khác (nghĩa là không phải Scala) có liên quan, các loại sr ở trên là java.lang.Object.

Đối với chính Scala, một số thông tin bổ sung được lưu trữ trong chú thích, cung cấp thông tin chính xác về các loại này khi Scala hiểu chúng.

Các vấn đề liên quan