2012-06-16 31 views
120

Tôi phải nói rằng tôi không hiểu các lớp liệt kê Scala. Tôi có thể sao chép-dán ví dụ từ tài liệu, nhưng tôi không có ý tưởng gì đang xảy ra.Hiểu các điều khoản scala

object WeekDay extends Enumeration { 
    type WeekDay = Value 
    val Mon, Tue, Wed, Thu, Fri, Sat, Sun = Value 
} 
import WeekDay._ 
  • nghĩa gì type WeekDay = Value và tại sao tôi phải viết đó?
  • Tại sao là val Mon = Value? Điều đó có nghĩa là gì?
  • Tại sao tôi phải nhập đối tượng WeekDay ? Và,
  • khi tôi viết val day = WeekDay.Mon, tại sao lại nhập WeekDay.Value, không nhập WeekDay?
+2

Tôi đã viết một tổng quan nhỏ về scala Liệt kê và lựa chọn thay thế, bạn có thể thấy nó hữu ích: pedrorijo.com/blog/scala-enums/ – pedrorijo91

Trả lời

149

đặc điểm Enumeration có một thành phần loại của điều tra (nó thực sự là một lớp bên trong, nhưng sự khác biệt không quan trọng ở đây).

Vì vậy, object WeekDay kế thừa thành viên loại đó. Dòng type WeekDay = Value chỉ là một bí danh loại . Nó rất hữu ích, bởi vì sau khi bạn nhập nó ở nơi khác với import WeekDay._, bạn có thể sử dụng loại, ví dụ:

def isWorkingDay(d: WeekDay) = ! (d == Sat || d == Sun) 

Thay vào đó, một phiên bản tối thiểu sẽ chỉ được:

object WeekDay extends Enumeration { 
    val Mon, Tue, Wed, Thu, Fri, Sat, Sun = Value 
} 

và bạn không đã để nhập nội dung của object WeekDay, nhưng sau đó bạn sẽ cần phải sử dụng loại WeekDay.Value và để đủ điều kiện cho từng thành viên. Vì vậy, ví dụ sẽ trở thành

def isWorkingDay(d: WeekDay.Value) = ! (d == WeekDay.Sat || d == WeekDay.Sun) 

Câu hỏi thứ hai là về ý nghĩa của val Mon, ... = Value. Điều này thực sự rất khó hiểu nếu bạn không nhìn vào việc thực hiện Enumeration. Đây không phải là nhiệm vụ của một loại! Thay vào đó, hãy gọi phương thức được bảo vệ có cùng tên, Value, trả về trường hợp cụ thể loại Value.

Nó như vậy sẽ xảy ra rằng bạn có thể viết val a, b, c = foo tại Scala, và cho mỗi giá trị a, bc phương pháp foo sẽ được gọi một lần nữa và một lần nữa. Enumeration sử dụng thủ thuật này để tăng bộ đếm nội bộ sao cho mỗi giá trị là riêng lẻ.

Nếu bạn mở tài liệu API Scala cho Enumeration và nhấp vào Visibility: All, bạn sẽ thấy phương thức đó xuất hiện.

+2

Cảm ơn, điều này rất khó hiểu nhưng tôi nghĩ nó đúng. Thay vào đó, tôi sẽ sử dụng các lớp vỏ kín, có vẻ dễ dàng hơn 100%. –

+2

Cá nhân tôi cũng thích các lớp vỏ kín. Một chút chi tiết hơn, nhưng ít hokus-pokus với bộ đếm nội bộ có thể thay đổi và vv. Với Scala 2.10, có một số ý tưởng về cách liệt kê (không giống Java không phải là một ngôn ngữ xây dựng mà chỉ là một giải pháp thư viện) có thể được viết tốt hơn bằng cách sử dụng các macro. –

+0

@ 0__ Tôi có thể hỏi tại sao và làm thế nào để bạn sử dụng lớp kín để thay thế enum trong Scala? Có điều gì sai với Scala's Enumeration? – x1a0

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