2012-02-25 44 views
94

tôi thấy mã này trong blog này: Type-Level Programming in Scala:Toán tử `#` có nghĩa là gì trong Scala?

// define the abstract types and bounds 
trait Recurse { 
    type Next <: Recurse 
    // this is the recursive function definition 
    type X[R <: Recurse] <: Int 
} 
// implementation 
trait RecurseA extends Recurse { 
    type Next = RecurseA 
    // this is the implementation 
    type X[R <: Recurse] = R#X[R#Next] 
} 
object Recurse { 
    // infinite loop 
    type C = RecurseA#X[RecurseA] 
} 

Có một nhà điều hành # trong mã R#X[R#Next] mà tôi chưa bao giờ thấy. Vì rất khó để tìm kiếm nó (bị bỏ qua bởi các công cụ tìm kiếm), ai có thể cho tôi biết nó có ý nghĩa gì?

+0

"dấu thăng" đôi khi được gọi là "octathrop" (tìm kiếm trên google đã đưa tôi đến trang này). – philwalk

+2

Làm cho [octothorpe hoặc octothorp] (https://en.wikipedia.org/wiki/Number_sign) – smparkes

+0

Các nhà khai thác khác như # + và # - (xem https://github.com/tpolecat/doobie/blob/series /0.4.x/yax/h2/src/main/scala/doobie/h2/H2Transactor.scala)? Có danh sách toàn diện không? –

Trả lời

184

Để giải thích điều đó, trước hết chúng ta phải giải thích các lớp lồng nhau trong Scala. Hãy xem xét ví dụ đơn giản này:

class A { 
    class B 

    def f(b: B) = println("Got my B!") 
} 

Bây giờ hãy thử một cái gì đó với nó:

scala> val a1 = new A 
a1: A = [email protected] 

scala> val a2 = new A 
a2: A = [email protected] 

scala> a2.f(new a1.B) 
<console>:11: error: type mismatch; 
found : a1.B 
required: a2.B 
       a2.f(new a1.B) 
       ^

Khi bạn khai báo một lớp bên trong một lớp học trong Scala, bạn đang nói rằng mỗi trường hợp của lớp đó có như vậy một phân lớp. Nói cách khác, không có lớp học A.B nhưng có các lớp học a1.Ba2.B và chúng là các lớp khác nhau, vì thông báo lỗi cho chúng tôi biết ở trên.

Nếu bạn không hiểu điều đó, hãy tìm kiếm các loại phụ thuộc vào đường dẫn.

Bây giờ, # giúp bạn có thể tham khảo các lớp lồng nhau đó mà không hạn chế nó vào một cá thể cụ thể. Nói cách khác, không có A.B, nhưng có A#B, có nghĩa là B lớp lồng nhau là bất kỳ phiên bản nào của A.

Chúng ta có thể thấy điều này trong công việc bằng cách thay đổi mã trên:

class A { 
    class B 

    def f(b: B) = println("Got my B!") 
    def g(b: A#B) = println("Got a B.") 
} 

Và cố gắng nó ra:

scala> val a1 = new A 
a1: A = [email protected] 

scala> val a2 = new A 
a2: A = [email protected] 

scala> a2.f(new a1.B) 
<console>:11: error: type mismatch; 
found : a1.B 
required: a2.B 
       a2.f(new a1.B) 
       ^

scala> a2.g(new a1.B) 
Got a B. 
+0

Ví dụ tuyệt vời. Tôi hoàn toàn chấp nhận rằng nó hoạt động theo cách đó, nhưng khó có thể hiểu được điều này: scala> classOf [A # B] res7: Class [A # B] = hạng A $ B scala> classOf [aB] res8 : Lớp [aB] = lớp A $ B . có nghĩa là, họ có cùng loại thực sự? – Chiron

+2

Giá trị của chúng có cùng biểu diễn chuỗi - và chúng có thể bằng nhau. 'Lớp' là một biểu diễn thời gian chạy của các lớp Java và nó bị giới hạn ngay cả trong Java. Ví dụ, 'Danh sách ' và 'Danh sách ' có cùng thời gian chạy 'Lớp'. Nếu 'Lớp' không đủ phong phú để đại diện cho các kiểu _Java_, nó gần như vô dụng khi biểu diễn các kiểu _Scala_. Một lần nữa, 'res7: Class [A # B] = class A $ B', bên trái của dấu bằng là một kiểu, bên phải của kiểu equals nếu một giá trị là biểu diễn Java _runtime_ của một lớp. –

8

Được gọi là phép chiếu loại và được sử dụng để truy cập các thành viên loại.

scala> trait R { 
    | type A = Int 
    | } 
defined trait R 

scala> val x = null.asInstanceOf[R#A] 
x: Int = 0 
+4

Đây không phải là câu trả lời. Nó về cơ bản cho thấy cùng một mã như câu hỏi, chỉ hơi rút ngắn. Điều gì là, ví dụ sự khác biệt để ký hiệu điểm? Tôi sẽ sử dụng số này ở đâu trong mã thực? – notan3xit

+1

@ notan3xit có thể đó không phải là câu trả lời cho những gì bạn muốn hỏi.Nhưng những gì bạn hỏi là "... mà tôi chưa bao giờ thấy. Vì nó rất khó để tìm kiếm nó (bị bỏ qua bởi các công cụ tìm kiếm), những người có thể cho tôi biết nó có nghĩa là gì?" – nafg

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