2012-07-15 36 views
7

Tôi thấy bây giờ mà có một câu hỏi liên quan yêu cầu những gì các nhà khai thác (<: <, <% <, =: =) làm ở đây:Làm thế nào để thực hiện Scala chính xác của <: <, <% <, =: = làm việc trong trình biên dịch?

What do <:<, <%<, and =:= mean in Scala 2.8, and where are they documented?

Nhưng tôi vẫn bối rối về việc thực hiện. Cụ thể, tôi giả sử rằng khi bạn đã đặt một thông số tiềm ẩn xác nhận mối quan hệ cụ thể, thì bạn có thể sử dụng các biến như thể chúng đã được tự động truyền đúng cách, ví dụ: điều này sẽ biên dịch:

class Foo[T](a: T) { 
    def splitit(implicit ev: T <:< String) = a split " " 
} 

Nhưng điều này thực sự hoạt động như thế nào trong trình biên dịch? Có một số hỗ trợ trình biên dịch ma thuật cho các nhà khai thác này, và nếu không, cơ chế cơ bản cho phép nó suy ra loại quan hệ này từ định nghĩa là gì? (Có phải cơ chế này được thêm vào đặc biệt để cho phép các toán tử này hoạt động và cụ thể như thế nào đối với các toán tử cụ thể này không?) Có vẻ như một chút phép thuật là bạn có thể đặt một tham số ngầm định như thế này.

+2

Nguồn cho chúng https://github.com/scala/scala/blob/v2.9.2/src/library/scala/Predef.scala#L394 – pedrofurla

Trả lời

8

Việc triển khai hơi phức tạp, nhưng không có gì huyền diệu.

Có một phương pháp tiềm ẩn trong Predef có thể cung cấp một giá trị kiểu A <:< A cho bất kỳ A

implicit def conforms[A]: A <:< A 

Khi bạn cố gắng để gọi phương pháp của bạn, nó sẽ cho một giá trị tiềm ẩn của loại T <:< String. Trình biên dịch sẽ kiểm tra xem nếu conforms[T] là một giá trị hợp lệ. Giả sử TNothing thì sẽ có giá trị ẩn Nothing <:< Nothing trong phạm vi sẽ cho phép phương thức của bạn gọi để biên dịch. Do cách <:< được định nghĩa

sealed abstract class <:<[-From, +To] 

From được phép thay đổi lên và To được phép thay đổi xuống. Vì vậy, Nothing <:< Nothing vẫn là Nothing <:< String hợp lệ kể từ Nothing là một loại phụ của String. A String <:< String cũng sẽ là Nothing <:< String hợp lệ kể từ String là siêu kiểu của Nothing (nhưng trình biên dịch dường như luôn chỉ chọn loại đầu tiên).

Bạn có thể gọi các phương thức của String vào nó vì <:< cũng mở rộng => aka Function1 và đóng vai trò như một chuyển đổi ngầm T-String, mà về cơ bản kết thúc lên làm một dàn diễn viên an toàn.

=:= cũng giống như vậy ngoại trừ nó được xác định mà không có bất kỳ chú thích phương sai nào, vì vậy các loại phải khớp chính xác.

<%< được định nghĩa như <:< nhưng phương pháp ngầm là một chút khác nhau, nó bổ sung thêm tham số khác để xác định một cái nhìn bị ràng buộc

implicit def conformsOrViewsAs[A <% B, B]: A <%< B 

Nó cũng bị phản đối.

+0

Cảm ơn!Sau đây là chìa khóa để giải thích cách trình biên dịch cho phép bạn gọi các phương thức String (hoặc bất kỳ thứ gì): _Bạn có thể gọi các phương thức String trên nó vì <: aka Function1 và phục vụ như một chuyển đổi ngầm từ T thành String, mà về cơ bản kết thúc lên làm một dàn diễn viên an toàn._ –

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