Для чего нужен enum

Перечисления в C#: как правильно использовать enum

В C# есть много крутых инструментов, которые позволяют улучшить любой код. Один из них — enum. Давайте разберёмся, что это и как с ним работать.

Для чего нужен enum. Смотреть фото Для чего нужен enum. Смотреть картинку Для чего нужен enum. Картинка про Для чего нужен enum. Фото Для чего нужен enum

Для чего нужен enum. Смотреть фото Для чего нужен enum. Смотреть картинку Для чего нужен enum. Картинка про Для чего нужен enum. Фото Для чего нужен enum

Списки перечисления (или enum) сокращают код и улучшают его читаемость. В этой статье мы создадим enum и научимся применять его эффективно.

Что такое enum в C#

Это список однотипных значений: цветов, состояний, способов выравнивания и так далее. Например, в C# существует встроенный список цветов:

То есть нам не нужно вручную вводить код цвета — вместо этого мы просто выбираем значение из заранее составленного списка.

Для чего нужен enum. Смотреть фото Для чего нужен enum. Смотреть картинку Для чего нужен enum. Картинка про Для чего нужен enum. Фото Для чего нужен enum

В самом enum тоже не хранится код цвета. Цифра 9 на примере выше — это индекс элемента в списке. Логика изменения цвета в нашем случае примерно такая:

Для чего нужен enum. Смотреть фото Для чего нужен enum. Смотреть картинку Для чего нужен enum. Картинка про Для чего нужен enum. Фото Для чего нужен enum

Пишет о программировании, в свободное время создает игры. Мечтает открыть свою студию и выпускать ламповые RPG.

Как создать enum в C#

Создайте отдельный файл и назовите его так, чтобы понять, какой это список. Например, Direction.cs:

После объявления нового enum он используется как тип данных:

Вы можете указать и какие-то собственные значения для элементов. Например, коды ответа веб-сервера:

По умолчанию тип значения — int, но он изменяется на любой другой целочисленный тип:

Как использовать enum в C#

Самый простой пример — конструкции if и switch.

Вот результат работы такой программы:

Для чего нужен enum. Смотреть фото Для чего нужен enum. Смотреть картинку Для чего нужен enum. Картинка про Для чего нужен enum. Фото Для чего нужен enum

Также вы можете использовать enum вместе с полиморфизмом.

Таким образом вы получите код, который очень быстро читается. И теперь не нужно думать, какой метод использовать, — благодаря полиморфизму всё выглядит почти как человеческая речь: set item type — Food (указать тип предмета — Еда).

Другая хорошая практика — использовать enum в качестве возвращаемого типа для методов, в которых ошибка может произойти по разным причинам. Например, отправка данных на сервер.

Этот метод возвращает три сообщения в зависимости от ситуации:

Конечно, допустимо куда больше вариантов: от ошибки базы данных до превышения времени ожидания.

Как enum помогает улучшить читаемость

Представим, что у нас есть класс Item со следующими полями:

Все эти значения передаются объекту через конструктор, поэтому инициализация выглядит так:

Без enum со временем вы забудете, за что отвечает третий аргумент, и вам придётся каждый раз проверять реализацию класса, чтобы освежить память. Или вы добавите новые типы предметов, из-за чего таких аргументов ( isArmor, isPotion) станет ещё больше:

Избежать таких неприятных моментов как раз и помогает enum: создайте перечисление ItemType и передавайте в конструктор его.

С первого взгляда понятно, что здесь имеется в виду.

Источник

Enum в PHP 8.1 — для чего нужен enum, и как реализован в PHP

Зачем нужны enum?

Зачем вообще нужны enum? По сути они служат цели улучшенного описания типов. Давайте рассмотрим пример без енумов и с ними. Допустим, у нас продаются машины трех цветов: красные, черные и белые. Как описать цвет, какой тип выбрать?

Это приводит к тому, что многие php-программисты заводят константы и объединяют их в одном классе, чтобы явно видеть все варианты.

Поэтому здесь нужен не класс, а отдельный тип. Этот тип называется enum

Pure enum

В самом простом случае (pure enum), enum описывается так:

Описав такой тип, мы можем использовать его везде:

Enum со скалярами

Но если бы это было всё, то было бы слишком просто. После названия enum можно указать скалярный тип, например string. И у каждого кейса указать скалярное значение. Это может быть полезно для некоторых целей, например для сортировки или записи в базу данных.

Скалярное значение можно получить потом так:

И наоборот, т.е. получить case через значение, тоже можно:

Помимо полей «case» в enum может быть еще много всего. По сути это разновидность класса. Там могут быть методы, он может реализовывать интерфейсы или использовать трейты.

Кстати, обратите внимание на работу с енамами в конструкции match. Похоже, match затевался именно для них.

Лично я горячо одобряю введение enum в PHP, это очень удобно и читабельно, и в большинстве языков, где есть какие-никакие типы, enum уже давно есть (кроме, разве что Go).

Дальше — больше. Tagged Unions (тип-сумма)

Есть RFC, которые развивают идею enums дальше, чтобы можно было хранить в одном enum значения разных типов. Как в языке Rust, например. Тогда можно будет сделать, допустим, enum Result с двумя case-ами Result::Ok и Result::Err, причем эти объекты будут хранить данные: Ok будет хранить результат, а Err — ошибку, у каждого из этих значений будет свой тип.

И всё это не в Расте или Хаскеле, а в PHP!

Об этом мы расскажем в деталях в ближайших постах телеграм-канала Cross Join, не забудьте подписаться.

Источник

Быстрый ENUM

Зачем нужно перечисление (enum)

(если вы все знаете — опуститесь до секции «Перечисления в стандартной библиотеке»)

Представьте, что вам нужно описать набор всех возможных состояний сущностей в собственной модели базы данных. Скорее всего, вы возьмёте пачку констант, определенных прямо в пространстве имен модуля:

… или как статические атрибуты класса:

Такой подход поможет сослаться на эти состояния по мнемоническим именам, в то время как в вашем хранилище они будут представлять собой обычные целые числа. Таким образом вы одновременно избавляетесь от магических чисел, разбросанных по разным участкам кода, заодно делая его более читабельным и информативным.

Или же ваш класс становится таким:

Наконец, именованный кортеж превращается в:

Уже неплохо — теперь он гарантирует, что и значение состояния и заглушка перевода отображаются на языки поддерживаемые UI. Но вы можете заметить, что код, использующий эти отображения, превратился в бардак. Каждый раз, пытаясь присвоить значение сущности, приходится извлекать значение с индексом 0 из используемого вами отображения:

илиили
И так далее. Помните, что первые два подхода, использующие константы и атрибуты класса, соответственно, страдают от изменяемости.

И вот перечисления приходят к нам на помощь

Вот и все. Теперь вы можете легко перебирать перечисление в вашем рендере (синтаксис Jinja2):

Перечисление является неизменяемым как для набора элементов — нельзя определить новый член перечисления во время выполнения и нельзя удалить уже определенный член, так и для тех значений элементов, которые он хранит — нельзя [пере]назначать любые значения атрибута или удалять атрибут.

В вашем коде вы просто присваиваете значения вашим сущностям, вот так:

Все достаточно понятно, информативно и расширяемо. Вот для чего мы используем перечисления.

Как мы смогли сделать его быстрее?

Перечисление из стандартной библиотеки довольно медленное, поэтому мы спросили себя — можем ли мы ускорить его? Как оказалось — можем, а именно, реализация нашего перечисления:

Slots

К примеру, можно использовать объявление класса с помощью __slots__ — в этом случае все экземпляры классов будут иметь только ограниченный набор свойств, объявленных в __slots__ и всех __slots__ родительских классов.

Descriptors

По умолчанию интерпретатор Python возвращает значение атрибута объекта напрямую (при этом оговоримся, что в данном случае значение — это тоже объект Python, а не, например, unsigned long long в терминах языка Си):
value = my_obj.attribute # это прямой доступ к значению атрибута по указателю, который объект хранит для этого атрибута.

Перечисления в стандартной библиотеке

Таким образом, вся последовательность вызовов может быть представлена следующими псевдокодом:

Мы написали простой скрипт демонстрирующий вывод, описанный выше:

И после выполнения скрипт выдал нам следующую картинку:
Для чего нужен enum. Смотреть фото Для чего нужен enum. Смотреть картинку Для чего нужен enum. Картинка про Для чего нужен enum. Фото Для чего нужен enum

Сравните с нашим FastEnum:

Что видно на следующем изображении:
Для чего нужен enum. Смотреть фото Для чего нужен enum. Смотреть картинку Для чего нужен enum. Картинка про Для чего нужен enum. Фото Для чего нужен enum

Все это действительно происходит внутри стандартной реализации перечислений каждый раз, когда вы обращаетесь к свойствам name и value их членов. Это же и причина, по которой наша реализация быстрее.

Наш подход

Свою реализацию перечислений мы создавали с оглядкой на элегантные перечисления в C и прекрасные расширяемые перечисления в Java. Основные функции, которые мы хотели реализовать у себя, были следующими:

Каковы дополнительные фишки?

FastEnum не совместим ни с какой версией Python до 3.6, поскольку повсеместно использует аннотации типов, внедренные в Python 3.6. Можно предположить, что установка модуля typing из PyPi поможет. Краткий ответ — нет. Реализация использует PEP-484 для аргументов некоторых функций, методов и указателей на тип возвращаемого значения, поэтому любая версия до Python 3.5 не поддерживается из-за несовместимости синтаксиса. Но, опять же, самая первая строка кода в __new__ метакласса использует синтаксис PEP-526 для указания типа переменной. Так что Python 3.5 тоже не подойдет. Можно перенести реализацию на более старые версии, хотя мы в Qrator Labs, как правило, используем аннотации типов когда это возможно, так как это сильно помогает в разработке сложных проектов. Ну и в конце-концов! Вы же не хотите застрять в Python до версии 3.6, поскольку в более новых версиях нет обратной несовместимости с вашим существующим кодом (при условии, что вы не используете Python 2), а ведь в реализации asyncio была проделана большая работа по сравнению с 3.5, на наш взгляд, стоящая незамедлительного обновления.

Однако, существуют некоторые ограничения: все имена членов перечисления должны быть написаны ЗАГЛАВНЫМИ буквами, иначе они не будут обработаны метаклассом.

Наконец, вы можете объявить базовый класс для ваших перечислений (имейте в виду, что базовый класс может сам использовать метакласс, поэтому вам не нужно предоставлять метакласс всем подклассам) — достаточно определить общую логику (атрибуты и методы) в этом классе и не определять членов перечисления (так что класс не будет «финализирован»). После можно объявить столько наследующих классов этого класса, сколько захотите, а сами наследники при этом будут иметь общую логику.

Псевдонимы и как они могут помочь

Предположим, что у вас есть код, использующий:

И что класс MyEnum объявлен следующим образом:

Теперь, вы решили что хотите сделать кое-какой рефакторинг и перенести перечисление в другой пакет. Вы создаете что-то вроде этого:

Где MyMovedEnum объявлен так:

Вот и все. При перезапуске ваших приложений на этапе unpickle все члены перечисления будут переобъявлены как экземпляры MyMovedEnum и станут связаны с этим новым классом. В тот момент, когда вы будете уверены, что все ваши хранимые, например, в базе данных, объекты были повторно десериализованы (и, возможно, сериализованы опять и сохранены в хранилище) — вы можете выпустить новый релиз, в котором ранее помеченный как устаревший класс MyEnum может быть объявлен более ненужным и удаленным из кодовой базы.

Источник

Перечисления (enum): для чего они нужны? Как, когда и какими перечислениями уместнее пользоваться?

Для чего нужен enum. Смотреть фото Для чего нужен enum. Смотреть картинку Для чего нужен enum. Картинка про Для чего нужен enum. Фото Для чего нужен enumДля чего нужны сужающие преобразования как они работают и на сколько они важны?
Я читаю одну книгу и застрял на одной теме «Преобразования», и там есть такой вот код double х.

Что за драйвера такие, для чего они и нужны ли они вообще?
Что за драйвера такие, для чего они и нужны ли они вообще? 1 Intel SATA Preinstall driver (For.

Зачем нужны перечисления enum?
Зачем нужны перечисления enum? Почему нельзя просто использовать массив? Объясните в чем плюсы.

Struts для чего они нужны?
Привет всем! Сразу прошу не бить ногами, если кому-то вопрос показался идиотским. Но дело в том.

Решение

Добавлено через 1 минуту
Photofenix, можно задать безымянный enum:

Так вот, такие состояния мне было удобно хранить с помощью переменной типа enum, в списке констант которого я указывал наименования состояний. В данном случае, значения самих констант меня не интересовали (смешно, но преподаватель по какой-то причине хотела забраковать такой подход, показав, что я ошибаюсь (типа значения этих констант всё-таки играют роль в моём коде), но, переставив несколько значений в моём списке, не добилась своего).

Ну и, конечно, удобно просто называть состояния своими именами, а не 1, 2, 3.

Модераторы\администраторы, почему съедаются слова в уже написанном тексте? CTRL+Z, вроде, не нажимал.

Добавлено через 2 часа 24 минуты

Источник

Гайд по использованию enum в Python

Для чего нужен enum. Смотреть фото Для чего нужен enum. Смотреть картинку Для чего нужен enum. Картинка про Для чего нужен enum. Фото Для чего нужен enum

Модуль enum содержит в себе тип для перечисления значений с возможностью итерирования и сравнения. Его можно использовать для создания понятных обозначений вместо использования чисел (для которых приходится помнить, какое число что обозначает) или строк (в которых легко опечататься и не заметить).

Создание

Итерирование

При итерировании по классу вы пройдёте по атрибутам.

Цикл будет идти по элементам в том порядке, в котором они указаны при создании класса. Названия и значения никак не влияют на порядок.

Сравнение перечислений

Так как элементы перечислений не упорядочены, то они поддерживают сравнение только по названию или значению.

IntEnum

Уникальные значения в перечислениях

Элементы перечисления с одинаковыми значениями являются несколькими названиями, указывающими на один и тот же объект.

Так как by_design и closed являются синонимами для других элементов, то они не появляются как элементы в циклах. Истинным считается название, указанное первым при объявлении.

Если вы хотите, чтобы все элементы обязательно имели разные значения, то добавьте декоратор @unique перед объявлением класса.

Элементы с повторяющимися значениями будут вызывать ValueError во время интерпретации.

Другой способ создания перечислений

Иногда удобнее не хардкодить элементы перечисления, а указывать их в более удобном виде. Для этого можно передать значения в конструктор класса:

Аргумент value является названием перечисления, которое используется для создания представления элементов. Второй аргумент names принимает список названий в перечислении. Если подать одну строку, то она будет разбита по пробельным символам и запятым, а значения будут числами, начиная с 1.

Также аргумент name принимает список пар названиезначение, либо аналогичный словарь.

Передача списка пар позволяет сохранить порядок элементов, аналогично случаю, где мы объявляли атрибуты.

Другие типы значений

В этом примере каждое значение является парой из числового id и списка строк, описывающих возможный переход из данного состояния.

Данный пример аналогичен предыдущему, но в нём используются словари вместо tuple для удобства.

Источник

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *