[Разработка веб-сайтов, PHP, Программирование] Enum в PHP 8.1 — для чего нужен enum, и как реализован в PHP
Автор
Сообщение
news_bot ®
Стаж: 6 лет 9 месяцев
Сообщений: 27286
Через несколько дней заканчивается голосование по первой итерации реализации enum в PHP 8.1. Уже видно, что голосов “за” гораздо больше, так что давайте кратко пройдемся и посмотрим, что же нам приготовили авторы языка.
Зачем нужны enum?
Зачем вообще нужны enum? По сути они служат цели улучшенного описания типов. Давайте рассмотрим пример без енумов и с ними. Допустим, у нас продаются машины трех цветов: красные, черные и белые. Как описать цвет, какой тип выбрать?
class Car {
private string $color;
function setColor(string $color): void {
$this->color = $color;
}
}
Если мы опишем цвет машины как простой string, то во-первых при вызове $myCar->setColor(..) непонятно, что за строку туда писать. “red” или “RED” или “#ff0000”, а во вторых, легко ошибиться, просунув туда случайно что-то не то (пустую строку, к примеру). То же самое будет, если использовать не строки, а числа, например.
Это приводит к тому, что многие php-программисты заводят константы и объединяют их в одном классе, чтобы явно видеть все варианты.
class Color {
public const RED = "red";
public const BLACK = "black";
public const WHITE = "white";
}
и задавая цвет, пишут $myCar->setColor(Color::RED);
Уже лучше. Но если мы впервые видим метод $myCar->setColor(...), мы можем и не знать, что где-то есть константы для цветов. И мы всё еще можем сунуть туда любую строку без какого-либо сообщения об ошибке.
Поэтому здесь нужен не класс, а отдельный тип. Этот тип называется enum
Pure enum
В самом простом случае (pure enum), enum описывается так:
enum Color {
case Red;
case Black;
case White;
}
Описав такой тип, мы можем использовать его везде:
class Car {
private Color $color;
function setColor(Color $color): void {
$this->color = $color;
}
}
Из сигнатуры метода всё сразу видно, какие варианты есть. И метод setColor можно использовать только так: $myCar->setColor(Color::White), никаких строк и доморощенных списков констант. Ничего лишнего не сунешь. Читабельность и поддерживаемость кода стала выше.
Каждый из case-ов (Color::Red, Color::Black, Color::White) является объектом типа Color (можно проверить через instanseof ). Т.е. под капотом это не числа 0,1,2 как в некоторых языках, а именно объекты. Их нельзя сравнивать оператором >, например. У каждого такого объекта есть встроенное свойство $name:
print Color::Red->name; // вернет строку “Red”
Enum со скалярами
Но если бы это было всё, то было бы слишком просто. После названия enum можно указать скалярный тип, например string. И у каждого кейса указать скалярное значение. Это может быть полезно для некоторых целей, например для сортировки или записи в базу данных.
enum Color: string {
case Red = "R";
case Black = "B";
case White = "W";
}
Скалярное значение можно получить потом так:
Color::Red->value //вернет строку “R”
И наоборот, т.е. получить case через значение, тоже можно:
Color::from("R") // вернет объект Color::Red
Помимо полей "case" в enum может быть еще много всего. По сути это разновидность класса. Там могут быть методы, он может реализовывать интерфейсы или использовать трейты.
Пример из RFC.
interface Colorful {
public function color(): string;
}
trait Rectangle {
public function shape(): string {
return "Rectangle";
}
}
enum Suit implements Colorful {
use Rectangle;
case Hearts;
case Diamonds;
case Clubs;
case Spades;
public function color(): string {
return match($this) {
Suit::Hearts, Suit::Diamonds => 'Red',
Suit::Clubs, Suit::Spaces => 'Black',
};
}
}
При этом $this будет тот конкретный объект case, для которого мы вызываем метод.
Кстати, обратите внимание на работу с енамами в конструкции match. Похоже, match затевался именно для них.
Лично я горячо одобряю введение enum в PHP, это очень удобно и читабельно, и в большинстве языков, где есть какие-никакие типы, enum уже давно есть (кроме, разве что Go).
Дальше — больше. Tagged Unions (тип-сумма)
Есть RFC, которые развивают идею enums дальше, чтобы можно было хранить в одном enum значения разных типов. Как в языке Rust, например. Тогда можно будет сделать, допустим, enum Result с двумя case-ами Result::Ok и Result::Err, причем эти объекты будут хранить данные: Ok будет хранить результат, а Err — ошибку, у каждого из этих значений будет свой тип.
И всё это не в Расте или Хаскеле, а в PHP!
Об этом мы расскажем в деталях в ближайших постах телеграм-канала Cross Join, не забудьте подписаться.
===========
Источник:
habr.com
===========
Похожие новости:
- [Разработка веб-сайтов, Программирование] Custom Elements из Angular в Angular
- [Программирование, Assembler, Научно-популярное, Старое железо, DIY или Сделай сам] Пишем программу для компьютера ALTAIR 8800 1975г выпуска
- [Firefox, Разработка веб-сайтов, Open source, Google Chrome, Браузеры] Невменяемый, необъятный масштаб браузеров (перевод)
- [Программирование, Rust] Размышления о Rust
- [Программирование] Mutation Driven Development
- [Python, Программирование, Django] Конвертеры маршрутов в Django 2.0+ (path converters)
- [Настройка Linux, Разработка веб-сайтов, CSS, JavaScript] Просто вертикальный монитор не значит, что я на телефоне (перевод)
- [Программирование, Go] Создаем бессерверное приложение с помощью Azure Functions и Go (перевод)
- [Системное администрирование, Программирование, Кодобред, *nix, Оболочки] Консольный менеджер сертификатов для JKS/PCKS12
- [PHP, Анализ и проектирование систем, NoSQL] Паспортный контроль, или Как сжать полтора гигабайта до 42 мегабайт
Теги для поиска: #_razrabotka_vebsajtov (Разработка веб-сайтов), #_php, #_programmirovanie (Программирование), #_php, #_enum, #_razrabotka_vebsajtov (
Разработка веб-сайтов
), #_php, #_programmirovanie (
Программирование
)
Вы не можете начинать темы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете голосовать в опросах
Вы не можете прикреплять файлы к сообщениям
Вы не можете скачивать файлы
Текущее время: 22-Ноя 19:06
Часовой пояс: UTC + 5
Автор | Сообщение |
---|---|
news_bot ®
Стаж: 6 лет 9 месяцев |
|
Через несколько дней заканчивается голосование по первой итерации реализации enum в PHP 8.1. Уже видно, что голосов “за” гораздо больше, так что давайте кратко пройдемся и посмотрим, что же нам приготовили авторы языка. Зачем нужны enum? Зачем вообще нужны enum? По сути они служат цели улучшенного описания типов. Давайте рассмотрим пример без енумов и с ними. Допустим, у нас продаются машины трех цветов: красные, черные и белые. Как описать цвет, какой тип выбрать? class Car {
private string $color; function setColor(string $color): void { $this->color = $color; } } Если мы опишем цвет машины как простой string, то во-первых при вызове $myCar->setColor(..) непонятно, что за строку туда писать. “red” или “RED” или “#ff0000”, а во вторых, легко ошибиться, просунув туда случайно что-то не то (пустую строку, к примеру). То же самое будет, если использовать не строки, а числа, например. Это приводит к тому, что многие php-программисты заводят константы и объединяют их в одном классе, чтобы явно видеть все варианты. class Color {
public const RED = "red"; public const BLACK = "black"; public const WHITE = "white"; } и задавая цвет, пишут $myCar->setColor(Color::RED); Уже лучше. Но если мы впервые видим метод $myCar->setColor(...), мы можем и не знать, что где-то есть константы для цветов. И мы всё еще можем сунуть туда любую строку без какого-либо сообщения об ошибке. Поэтому здесь нужен не класс, а отдельный тип. Этот тип называется enum Pure enum В самом простом случае (pure enum), enum описывается так: enum Color {
case Red; case Black; case White; } Описав такой тип, мы можем использовать его везде: class Car {
private Color $color; function setColor(Color $color): void { $this->color = $color; } } Из сигнатуры метода всё сразу видно, какие варианты есть. И метод setColor можно использовать только так: $myCar->setColor(Color::White), никаких строк и доморощенных списков констант. Ничего лишнего не сунешь. Читабельность и поддерживаемость кода стала выше. Каждый из case-ов (Color::Red, Color::Black, Color::White) является объектом типа Color (можно проверить через instanseof ). Т.е. под капотом это не числа 0,1,2 как в некоторых языках, а именно объекты. Их нельзя сравнивать оператором >, например. У каждого такого объекта есть встроенное свойство $name: print Color::Red->name; // вернет строку “Red”
Enum со скалярами Но если бы это было всё, то было бы слишком просто. После названия enum можно указать скалярный тип, например string. И у каждого кейса указать скалярное значение. Это может быть полезно для некоторых целей, например для сортировки или записи в базу данных. enum Color: string {
case Red = "R"; case Black = "B"; case White = "W"; } Скалярное значение можно получить потом так: Color::Red->value //вернет строку “R”
И наоборот, т.е. получить case через значение, тоже можно: Color::from("R") // вернет объект Color::Red
Помимо полей "case" в enum может быть еще много всего. По сути это разновидность класса. Там могут быть методы, он может реализовывать интерфейсы или использовать трейты. Пример из RFC. interface Colorful {
public function color(): string; } trait Rectangle { public function shape(): string { return "Rectangle"; } } enum Suit implements Colorful { use Rectangle; case Hearts; case Diamonds; case Clubs; case Spades; public function color(): string { return match($this) { Suit::Hearts, Suit::Diamonds => 'Red', Suit::Clubs, Suit::Spaces => 'Black', }; } } При этом $this будет тот конкретный объект case, для которого мы вызываем метод. Кстати, обратите внимание на работу с енамами в конструкции match. Похоже, match затевался именно для них. Лично я горячо одобряю введение enum в PHP, это очень удобно и читабельно, и в большинстве языков, где есть какие-никакие типы, enum уже давно есть (кроме, разве что Go). Дальше — больше. Tagged Unions (тип-сумма) Есть RFC, которые развивают идею enums дальше, чтобы можно было хранить в одном enum значения разных типов. Как в языке Rust, например. Тогда можно будет сделать, допустим, enum Result с двумя case-ами Result::Ok и Result::Err, причем эти объекты будут хранить данные: Ok будет хранить результат, а Err — ошибку, у каждого из этих значений будет свой тип. И всё это не в Расте или Хаскеле, а в PHP! Об этом мы расскажем в деталях в ближайших постах телеграм-канала Cross Join, не забудьте подписаться. =========== Источник: habr.com =========== Похожие новости:
Разработка веб-сайтов ), #_php, #_programmirovanie ( Программирование ) |
|
Вы не можете начинать темы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете голосовать в опросах
Вы не можете прикреплять файлы к сообщениям
Вы не можете скачивать файлы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете голосовать в опросах
Вы не можете прикреплять файлы к сообщениям
Вы не можете скачивать файлы
Текущее время: 22-Ноя 19:06
Часовой пояс: UTC + 5