Hiểu các phép liệt kê theo tỉ lệ


122

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 và dán ví dụ từ tài liệu, nhưng tôi không biết chuyện gì đang xảy ra.

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

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

Những đặc điểm kín mang đến một giải pháp thay thế tuyệt vời - stackoverflow.com/questions/11203268/what-is-a-sealed-trait
Joey Baruch

Câu trả lời:


150

các Enumerationđặc điểm có thành viên loại Valueđại diện cho các yếu tố cá nhân thuộc kiểu liệt kê (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).

Do đó object WeekDaykế thừa thành viên kiểu đó. Dòng type WeekDay = Valuechỉ là một loại bí danh . Nó rất hữu ích, vì sau khi bạn nhập nó ở nơi khác import WeekDay._, bạn có thể sử dụng kiểu đó, 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ỉ là:

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

và bạn không phải nhập nội dung của object WeekDay, nhưng sau đó bạn sẽ cần sử dụng loại WeekDay.Valuevà để đủ điều kiện thành viên cá nhâ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à sự phân công của một kiểu! Thay vào đó, nó gọi một phương thức được bảo vệ có cùng tên , phương thứcValue này trả về một kiểu cụ thể Value.

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

Nếu bạn mở tài liệu API Scala Enumerationvà 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 trường hợp kín, nó có vẻ dễ dàng hơn 100%.
Karel Bílek

2
Cá nhân tôi cũng thích các lớp trường hợp kín. Dài dòng hơn một chút, nhưng ít hokus-pokus hơn với các bộ đếm bên trong có thể thay đổi, v.v. Với Scala 2.10, có một số ý tưởng về cách liệt kê (không giống như Java không phải là một cấu trúc ngôn 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 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 niêm phong để thay thế enum trong Scala? Có gì sai với Scala's Enumeration không?
x1a0 10/09/13

Điều gì sẽ xảy ra nếu Enum tự đánh giá mình có thành viên? Ví dụ, bạn sẽ xác định giờ mở cửa cho mỗi ngày trong tuần như: Thứ Hai (8,20), ..., Chủ Nhật (0,0) như thế nào?
simou

1
@simou thì bạn thực sự nên sử dụng một đặc điểm được niêm phong và các lớp con thực tế. Tuy nhiên, tôi khó có thể gọi tình huống đó là "sự liệt kê". Bạn có thể viết tốt hơn Open(Mon, 8, 20)và ngày sẽ vẫn là một bảng thống kê phẳng.
0__
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.