Tại sao chúng ta cần enum trong các ngôn ngữ gõ động?


32

Tôi đã đọc một số mã ở đây và thấy rằng một enum được sử dụng để lưu trữ tên của các thẻ html. Tại sao chúng ta cần phải làm điều này? Tôi được lợi gì khi sử dụng chiến lược này?

Tôi biết rằng các enum hữu ích như thế nào trong các ngôn ngữ được biên dịch hoặc gõ tĩnh nhưng khi tôi thấy các enum trong các ngôn ngữ được gõ động, tôi thấy tò mò, như mã ví dụ tôi đã trình bày ở trên. Vì vậy, câu hỏi về cơ bản sôi nổi tại sao chúng ta cần enum trong ngôn ngữ gõ động hoặc chúng ta cần chúng ở tất cả?


38
Câu hỏi này về cơ bản là "Tại sao chúng ta cần các loại" .
dùng11153

1
Bạn đã tìm kiếm repo để xem nó được gọi như thế nào? Điều đó có thể sẽ cho bạn hiểu rõ hơn về câu trả lời bạn nhận được.
RubberDuck

nếu bạn có: enum People { YOU, NPC, FOO, BAR }và một chức năng muốn có (Mọi người) int, bạn có thể cắm bất cứ thứ gì, thay vì sử dụng một số.
Evan Carslake

3
Bạn đang hỏi về mục đích của "enum" đặc biệt này hay về mục đích của enum nói chung, trong bất kỳ ngôn ngữ nào? Tôi giả sử câu trước, nhưng tất cả các câu trả lời hiện tại dường như nghĩ câu sau ...
meriton - đình công

Câu trả lời:


56

Một lợi ích là trình biên dịch có thể cho bạn biết nếu bạn vô tình gõ "QUẢNG CÁO" hoặc "FEILDSET" và cho phép bạn sửa nó ngay lập tức thay vì hành xử theo cách vô nghĩa khi chạy.

Mặc dù lợi ích hữu ích hơn nhiều đối với các ngôn ngữ được nhập tĩnh so với động, nhưng nó vẫn hữu ích ngay cả khi đó là lỗi thời gian chạy vì bạn sẽ nhận được thông báo cho biết có vấn đề với tuyên bố trường hợp của bạn chứ không phải dữ liệu của bạn.


4
@amon: bạn có thể, nhưng enums cung cấp cho bạn một cơ chế tiện dụng để đảm bảo bạn không có va chạm.
whatsisname

75
Một nơi tôi từng làm việc một lần trong một tháng đã theo đuổi một lỗi do ý tưởng sáng chói của ai đó để sử dụng hằng chuỗi thay vì enums, phông chữ kém của trình soạn thảo và một trường vô tình được đặt tên"PROF1LE_"
Gort the Robot

8
@amon Go làm chính xác điều này. Tuy nhiên, một điều hay về enums là trình biên dịch có thể kiểm tra xem câu lệnh chuyển đổi của bạn có trường hợp nào cho mọi giá trị enum có thể không.
weberc2

15
Mã này được viết vào những năm 80. Bạn có thể không nhận ra điều này, nhưng đây là thời đại mà một số nhà phát triển đã học cách phát triển trên máy đánh chữ vật lý, có thể không có một phím . Mặc dù thực sự tôi nhận ra rằng chuỗi trong câu hỏi là "Profi1e" ... đã hai mươi lăm năm, vì vậy bộ nhớ của tôi rõ ràng là không hoàn hảo.
Gort Robot

4
@DarrelHoffman: Tôi ngạc nhiên khi bạn ngạc nhiên. Trong Perl, tôi thường thấy mình gõ $1khi tôi có ý nghĩa $i. (Được cấp, tôi không bao giờ gõ f1lethay vì file- $1lỗi được bắt nguồn bởi thực tế $1rất phổ biến ở Perl - nhưng vẫn có lỗi, tất cả các loại đều phổ biến. Có lẽ nhà phát triển đã có mật khẩu prof1letrong đó, do đó dẫn đến nhầm lẫn. profiletrong bối cảnh không có mật khẩu.)
ruakh

22

Enums rất hữu ích cho các tình huống trong đó bạn có một bộ giá trị / thực thể cố định hợp lý. Chúng là tài liệu tự và cho phép trình biên dịch xác nhận những thứ mà nếu không còn thời gian. Chúng không bao giờ được sử dụng nếu tập hợp các giá trị có ý nghĩa không được biết hoặc không bị giới hạn nghiêm ngặt.

Một ví dụ hữu ích hơn sẽ là một cái gì đó giống như mã phản hồi HTTP. Thay vì có một phương thức lấy một số và cung cấp tên và / hoặc mô tả lỗi, bạn có thể có một tập hợp các enum với tên có ý nghĩa, mã và mô tả, v.v. trong một gói sạch có thẩm quyền trong các giá trị nào được phép và cần được xử lý.


1
"Tự viết tài liệu" là phần quan trọng nhất. Tôi thà kiểm tra xem còn status === GEOLOCATION_ACQUIREDhơn không status === 3, để người duy trì phần mềm đó hiểu chuyện gì đang xảy ra. Như bạn đã nói, nó cũng ngăn chặn các giá trị không hợp lệ.
Nicolas Bouliane

11

Enums không liên quan gì đến OOP và JavaScript không có enums. Thay vào đó, enum được sử dụng bất cứ khi nào có sự lựa chọn giữa một bộ giá trị cố định. Ví dụ, boolean là sự lựa chọn giữa đúng và sai, có thể được thực hiện như enum Bool { False, True }. Trong thư viện GUI, chúng tôi có thể có một bảng liệt kê để sắp xếp : enum HAlignment { LEFT = -1, CENTER = 0, RIGHT = 1 }.

Nó thường không liên quan như thế nào enum được thực hiện, phần quan trọng là mỗi giá trị có thể là khác biệt. Nhiều ngôn ngữ sử dụng số nguyên cho enums, mặc dù một số ngôn ngữ như Java hỗ trợ các đối tượng tùy ý.

Cho đến bây giờ, chúng ta cũng có thể sử dụng các hằng số, vd const int LEFT = -1, CENTER = 0, RIGHT = 1. Tuy nhiên, một trình biên dịch biết rằng các giá trị enum thuộc về nhau. Vì vậy, khi tôi chuyển qua các giá trị enum switch(value) {case LEFT: ...; case RIGHT: ...;}, trình biên dịch có thể cảnh báo tôi rằng tôi đã quên CENTERtrường hợp này. Đây có thể là một tiết kiệm thời gian đáng kể. Trong các ngôn ngữ không có enum hoặc không có cấu trúc trường hợp chuyển đổi, điều này có thể được mô phỏng với Mẫu khách truy cập, mặc dù điều đó hữu ích hơn khi có kiểu gõ tĩnh.

Ưu điểm khác là enums có thể được coi là một loại riêng biệt. Ví dụ, tôi có thể khai báo rằng một phương thức lấy một HAlignmenttham số, thay vì bất kỳ số nguyên nào. Sau đó, mã sẽ không biên dịch được nếu tôi cung cấp bất cứ thứ gì ngoại trừ một trong ba giá trị HAlocation có thể. Tuy nhiên, enum của C không được đóng gói tốt và các hằng số enum có thể được sử dụng thay thế cho nhau với các số nguyên. Các ngôn ngữ khác chặt chẽ hơn ở đây.

Trong JavaScript, chúng tôi không nhận được bất kỳ lợi ích nào trong số này. Ví dụ đã cho khai báo một đối tượng được coi là enum. Điều này có một số lợi thế cho lập trình viên, ví dụ như nó làm cho tài liệu dễ dàng hơn, nhóm tất cả các hằng số trên mạng thành một đối tượng duy nhất, khác. Tuy nhiên, nó chỉ là một quy ước rằng một đối tượng như vậy là giống như enum.

Vấn đề ở đây là HTML chỉ có một bộ thẻ hữu hạn và đã biết. Bạn có thể xem đặc tả HTML5 và đặt các tên thành phần đó làm enum vào mã của mình và do đó làm cho việc lén <blink>thẻ vào chương trình của bạn trở nên khó khăn hơn . Tốt hơn là mã hóa kiến ​​thức này ở một nơi để xả mã của bạn bằng các chuỗi ký tự đặc biệt (hoặc tệ hơn, số ma thuật).


Trong trường hợp đó nếu tôi chuyển <blink>sang một phương thức nào đó trong javascript thì không gì có thể ngăn tôi phải không? nhưng trong lời javachào vỡ ra :)
CodeYogi

@CodeYogi có, bởi vì JS không có hệ thống kiểu tĩnh và đặc biệt không có khái niệm về kiểu enum. Tuy nhiên, tôi có thể ghi lại một tham số phương thức khi mà Viking lấy một TagName, điều này sẽ dẫn một lập trình viên gọi nó vì nó foo(TagName.STRONG)tốt hơn một chút. Sẽ tốt hơn nữa nếu JS sẽ khiếu nại nếu trường không tồn tại, nhưng ở đây chúng tôi chỉ nhận được undefinednếu tôi thử TagName.BLINK. Nó không có giá trị nhiều trong JS, nhưng đó là một khởi đầu.
amon

Hmm, liên kết mã tôi đã đề cập ở trên sử dụng trình biên dịch đóng do đó có ý nghĩa ở đó.
CodeYogi

Clojure là một ngôn ngữ chức năng, vì vậy tôi không chắc OOP có liên quan đến câu hỏi như thế nào nhưng ngoài ra, điều quan trọng là phải phân biệt giữa các enum thường chỉ là một bộ số nguyên (không phải OO) và mẫu 'Kiểu an toàn enum' là OO và những gì Java hỗ trợ.
JimmyJames

@JimmyJames Tôi đang nói về JS, không phải về Clo j ure (mà, chạy trên nền tảng Java, cũng hỗ trợ OOP ở một mức độ nào đó). Câu hỏi đã được gắn thẻ với oop , đó là lý do tại sao tôi đề cập đến nó ngay từ đầu. Tôi thực sự không thấy làm thế nào các enum an toàn được kết nối với OOP, đó chỉ là một tính năng hệ thống loại (nhiều ngôn ngữ không phải OOP có hệ thống loại :-))
amon

3

Ngay cả khi ngôn ngữ của bạn không yêu cầu biên dịch, có thể bạn sẽ sử dụng một số loại IDE hoặc công cụ phát triển, có thể hỗ trợ tốt hơn cho một thứ như enum thay vì chỉ cho chuỗi.

Ví dụ: nếu bạn sử dụng một đối tượng như enum trong javascript, trình soạn thảo của bạn sẽ cung cấp cho bạn hoàn thành mã và trình kiểm tra mã của bạn như JSHint hoặc JSLint sẽ cảnh báo bạn, nếu bạn vô tình sử dụng sai giá trị.


Tôi nghĩ rằng rất nhiều phản hồi khác hoặc bỏ lỡ hoặc đánh bại xung quanh điểm này. Sử dụng một 'emum' trong một ngôn ngữ động có thể không làm được gì cho trình biên dịch, nhưng nó thực sự có thể giúp một số IDE, công cụ tài liệu nhất định và cũng không quên những người đang cố gắng hiểu mã.
Robert

2

Điểm của enum như vậy có thể là cung cấp cho Js Api (goog) một bộ / gói các thẻ được phép. Những cái nào? Những cái được định nghĩa bởi W3C HTML 4.01 ( xem tài liệu của enum ). Vì vậy, nó thiết lập ranh giới.

Có thể hoặc không thể là mục tiêu thực sự này, tuy nhiên nó sẽ hoạt động tốt cho mục đích đó.

Nếu bạn biết Javascript hoạt động như thế nào, mã nào đang làm là xác định một mảng được lập chỉ mục bởi các chuỗi :-). Giá trị nào là một chuỗi, nhưng nó có thể là bất kỳ thành phần nào khác có thuộc tính, hàm, v.v ... Hãy để trí tưởng tượng của bạn chạy miễn phí và bạn sẽ thấy lợi ích ở mọi nơi.

Bỏ qua một bên, tôi sử dụng enums rất nhiều để mô hình hóa và quản lý các máy trạng thái .

BẮT ĐẦU> IN_PROGRESS> XÁC NHẬN> HOÀN TẤT> ...

Trong java switch, cho phép các enum vì vậy khá dễ dàng để xác nhận các trạng thái thành một máy trạng thái , lặp lại tất cả các enum, để xác định các ưu tiên bằng cách thực hiện các enum phức tạp, ...

Tôi cũng sử dụng chúng để xác định các hằng số đánh máy và không thể thay đổi:

  • Có không

Ngoài ra các enum phức tạp (cho phép thực hiện các biến đổi / phân tích cú pháp an toàn)

  • Có (1, đúng), Không (0, sai)

Do enums thường thuộc về lớp mô hình của tôi (lõi), các tính năng của nó có thể truy cập được trên tất cả hệ thống, vì vậy nó trở thành một mô hình chức năng và tôi giữ một khớp nối thấp.

Có gì enums cho (trong số những thứ khác) là ranh giớitypification

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.