Навіщо нам потрібні переписки на динамічно набраних мовах?


32

Я читав тут якийсь код і побачив, що enum використовується для зберігання назв html-тегів. Чому нам взагалі потрібно це робити? Яку користь я отримую, використовуючи цю стратегію?

Я знаю, що корисні перерахунки в мовах, що складаються або статично набрані, але коли я бачу переліки на динамічно набраних мовах, мені стає цікаво, як приклад коду, який я показав вище. Отже, питання в основному зводиться до того, навіщо нам потрібні переписки в динамічно набраній мові чи вони взагалі потрібні?


38
Це питання в основному "Для чого нам потрібні типи" .
користувач11153

1
Ви шукали репо, щоб побачити, як воно називається? Це, ймовірно, допоможе вам краще зрозуміти відповіді, які ви отримали.
RubberDuck

якщо у вас є: enum People { YOU, NPC, FOO, BAR }і функція, яка хоче (Люди) int, ви можете підключити будь-що, замість того, щоб використовувати число.
Еван Карслайк

3
Ви запитуєте про мету цього конкретного "перерахунку" чи про мету переліків взагалі будь-якою мовою? Я припускаю, що перший, але всі поточні відповіді, здається, вважають останній ...
meriton - страйкують

Відповіді:


56

Перевага полягає в тому, що компілятор може повідомити вас про те, якщо ви випадково набрали "ADRESS" або "FEILDSET", і дозволить вам негайно виправити це, замість того, щоб вести себе безглуздо під час виконання.

Хоча вигода набагато корисніша в статично набраних мовах, ніж динамічна, вона все ще корисна, навіть якщо це помилка під час виконання, оскільки ви отримаєте повідомлення, що вказують на проблему із заявою справи, а не вашими даними.


4
@amon: ти міг би, але переписки дають тобі зручний механізм, щоб у тебе не було зіткнень.
whatsisname

75
Місце, на якому я працював один раз протягом місяця, переслідуючи помилку, спричинену чиєюсь яскравою ідеєю, використовувати струнні константи замість перерахунків, погані редакторські шрифти та поле, випадково назване"PROF1LE_"
Gort the Robot

8
@amon Go робить саме це. Однак одна з приємних рішень про перерахунки полягає в тому, що компілятор може перевірити, чи є у вашому операторі перемикання справочник для кожного можливого значення перерахунку.
weberc2

15
Цей код був написаний у 80-х роках. Ви можете цього не усвідомлювати, але це було в епоху, коли деякі розробники навчилися розробляти на фізичних машинках, які, можливо, не мали жодного ключа . Хоча насправді я усвідомлюю, що йдеться про "Profi1e" ... це вже двадцять п’ять років, тому пам'ять, очевидно, не ідеальна.
Gort the Robot

4
@DarrelHoffman: Я здивований, що ти здивований. У Perl, я часто ловлю себе друкуючи , $1коли я маю в виду $i. (Звичайно, я ніколи не вводити f1leзамість file- $1помилка грунтується тим , що $1є дуже поширеним явищем в Perl. - але все ж, помилки всіх видів звичайні Може Дев пароль з prof1leв ньому, таким чином , заливка їх помилкою profileв контекстах без пароля.)
ruakh

22

Енуми корисні для ситуацій, коли у вас є фіксований набір значень / сутностей, які є розумними. Вони самодокументовані та дозволяють компілятору перевірити речі, які в іншому випадку залишаться для виконання. Їх ніколи не слід використовувати, якщо набір значущих значень не відомий або не є суворо обмеженим.

Більш корисним прикладом може бути щось на кшталт кодів відповідей HTTP. Замість того, щоб мати метод, який приймає число та надає ім'я та / або опис помилки, ви можете мати набір перерахунків зі значущими іменами, кодом та описом тощо в одному чистому пакеті, який є авторитетним у тому, які значення є дозволено і потрібно обробляти.


1
"Самодокументація" - найважливіша частина. Я набагато краще перевірити, якщо status === GEOLOCATION_ACQUIREDніж status === 3, щоб людина, яка підтримує це програмне забезпечення, зрозуміла, що відбувається. Як ви сказали, це також запобігає недійсним значенням.
Nicolas Bouliane

11

Енуми не мають нічого спільного з OOP, а JavaScript не має перерахунків. Натомість перерахунки використовуються, коли є вибір між фіксованим набором значень. Наприклад, булевий вибір - це вибір між істинним і хибним, який може бути реалізований як enum Bool { False, True }. У бібліотеці GUI, ми могли б мати перерахування для вирівнювання: enum HAlignment { LEFT = -1, CENTER = 0, RIGHT = 1 }.

Зазвичай не має значення як реалізація перерахунку, важливою частиною є те, що кожне можливе значення є виразним. Багато мов використовують цілі числа для перерахунків, хоча деякі, як Java, підтримують довільні об'єкти.

До цього часу ми могли так само добре використовувати константи, наприклад const int LEFT = -1, CENTER = 0, RIGHT = 1. Однак компілятор знає, що значення enum належать разом. Тож коли я переключаю значення enum switch(value) {case LEFT: ...; case RIGHT: ...;}, компілятор може попередити мене, що я забув CENTERвипадок. Це може бути значною економією часу. Мови без перерахунків або без конструкції корпусу комутатора це можна змоделювати за допомогою Шаблона відвідувачів, хоча це корисніше за наявності статичного набору тексту.

Інша перевага полягає в тому, що до енумів можна трактувати як окремий тип. Наприклад, я можу заявити, що метод приймає HAlignmentпараметр, а не будь-яке ціле число. Код не вдасться скомпілювати, якщо я надаю щось, крім одного з трьох можливих значень HAlignment. Однак перерахунки С недостатньо інкапсульовані, і константи перерахунків можуть використовуватися взаємозамінно з цілими числами. Інші мови тут суворіші.

У JavaScript ми не отримуємо жодної з цих переваг. Наведений приклад оголошує об’єкт, який трактується як перерахунок. Це має деякі переваги для програміста, наприклад, це полегшує документування, групує всі "константи" в один об'єкт, ... Однак це лише умова про те, що такий об’єкт є перелічуваним.

Суть у тому, що HTML має лише обмежений та відомий набір тегів. Ви можете подивитися специфікацію HTML5 і ввести ці імена елементів як перерахунок у свій код, а тому ускладнить <blink>проникнення тегу до вашої програми. Краще кодувати ці знання в одному місці, щоб засмітити свій код спеціальними рядковими буквами (або ще гірше, магічними числами).


У такому випадку, якщо я перейду <blink>до якогось методу в javascript, нічого не могло б зупинити мене правильно? але javaпривіт перерви вільно :)
CodeYogi

@CodeYogi так, тому що JS не має системи статичного типу, і, зокрема, не має поняття типів enum. Однак я можу зафіксувати параметр методу як "бере TagName", що призведе до того, що програміст викликає його як foo(TagName.STRONG)трохи кращого. Було б навіть краще, якщо JS поскаржиться, якщо поля не існує, але тут ми отримуємо лише, undefinedякщо я спробую TagName.BLINK. У JS це не багато чого, але це початок.
амон

Гм, згадане вище посилання на код використовує компілятор закриття, тому є сенс.
CodeYogi

Clojure - це функціональна мова, тому я не впевнений, наскільки OOP має відношення до питання, але в стороні важливо розрізняти перерахунки, які, як правило, лише набір цілих чисел (а не OO), і шаблон "Typesafe enum", який є ОО і що підтримує Java.
JimmyJames

@JimmyJames Я говорю про JS, а не про Clo j ure (який, працюючи на платформі Java, певною мірою також підтримує OOP). Питання було позначене oop , саме тому я згадую його на початку. Я насправді не бачу, як ensafe переписки підключаються до OOP, це лише функція системи типу (у багатьох мовах, що не належать до OOP, є системи типів :-))
amon

3

Навіть якщо ваша мова не потребує компіляції, ви, ймовірно, використовуватимете якісь засоби IDE чи інструменти розробки, які можуть надати набагато кращу підтримку чимось на зразок перерахунку, ніж просто для рядків.

Якщо ви, наприклад, використовуєте об'єкт-буквальний об’єкт у javascript, ваш редактор видасть вам завершення коду, і ваш контролер коду, як-от JSHint або JSLint, попередить вас, якщо ви випадково використовуєте неправильне значення.


Я думаю, що багато інших відповідей або пропускають, або б'ють навколо цього моменту. Використання "emum" в динамічній мові може нічого не зробити для компілятора, але це дійсно може допомогти певним IDE, документаціям, а також не забувати людей, які намагаються зрозуміти код.
Роберт

2

Суть такого перерахунку може полягати в наданні Js Api (goog) набору / розшарування дозволених тегів. Котрий? Визначені W3C HTML 4.01 ( ознайомтеся з документацією enum ). Отже, це межі налаштувань.

Це може бути чи не бути справжньою метою, однак для цієї мети це буде чудово.

Якщо ви знаєте, як працює Javascript, то, що робить код, це визначення масиву, індексованого рядками :-). Яке значення - це рядок, але це може бути будь-який інший компонент з атрибутами, функціями тощо ... Нехай ваша фантазія запуститься, і ви побачите переваги всюди.

Крім JavaScript, я багато використовую enums для моделювання та управління державними машинами .

СТАРТ> IN_PROGRESS> ПІДТВЕРДЖЕНО> ЗАВЕРШЕНО> ...

В Java перемикач дозволяє перерахувань так досить легко для перевірки станів в державній машині , в циклі всього перерахування, щоб визначити пріоритети, роблячи комплексувати перерахувань, ...

Я також використовую їх для визначення типізованих і незмінюваних констант:

  • Так ні

Також складні переліки (що дозволяє робити безпечні перетворення / аналізатори)

  • Так (1, правда), Ні (0, помилково)

Завдяки перерахункам часто належить до мого шару моделі (core), його функції доступні для всієї системи, тому вона стає функціональною моделлю, і я зберігаю низьку зв'язок.

Те, що переживає (серед іншого), - це межі та типізація

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.