По умолчанию Enumerated Cases не имеет скалярного эквивалента. Это просто одноэлементные объекты. Однако существует множество случаев, когда Enumerated Case должен иметь возможность обращения к базе данных или аналогичному хранилищу данных, поэтому полезно иметь встроенный скалярный (и, следовательно, тривиально сериализуемый) эквивалент, определенный внутри.
Чтобы определить скалярный эквивалент для Enumeration, используется следующий синтаксис:
<?php
enum Suit: string
{
case Hearts = 'H';
case Diamonds = 'D';
case Clubs = 'C';
case Spades = 'S';
}
?>
Вариант, который имеет скалярный эквивалент, называется резервным случаем, поскольку он «поддерживается» более простым значением. Перечисление, содержащее все резервные случаи, называется «резервным перечислением». Backed Enum может содержать только Backed Cases. Pure Enum может содержать только Pure Cases.
Backed Enum может поддерживаться типами int
или string
, а данное перечисление одновременно поддерживает только один тип (то есть объединение типов int|string
). Если перечисление помечено как имеющее скалярный эквивалент, то все случаи должны иметь явно заданный уникальный скалярный эквивалент. Не существует автоматически сгенерированных скалярных эквивалентов (например, последовательных целых чисел). Поддерживаемые кейсы должны быть уникальными; два поддерживаемых случая перечисления могут не иметь одного и того же скалярного эквивалента. Однако константа может ссылаться на случай, эффективно создавая псевдоним.
Эквивалентные значения должны быть литералами или литеральными выражениями. Константы и постоянные выражения не поддерживаются. То есть 1 + 1
разрешено, но 1 + SOME_CONST
нет.
Поддерживаемые обращения имеют дополнительное свойство только для чтения value
, значение которого указано в определении.
<?php
print Suit::Clubs->value;
// Prints "C"
?>
Чтобы сделать value
свойство доступным только для чтения, переменная не может быть назначена ссылкой на него. То есть следующее выдает ошибку:
<?php
$suit = Suit::Clubs;
$ref = &$suit->value;
// Error: Cannot acquire reference to property Suit::$value
?>
Поддерживаемые перечисления реализуют внутренний интерфейс BackedEnum , который предоставляет два дополнительных метода:
from(int|string): self
возьмет скаляр и вернет соответствующий Enum Case. Если он не найден, он выдаст ValueError . Это в основном полезно в случаях, когда входной скаляр является доверенным, а отсутствующее значение перечисления следует рассматривать как ошибку остановки приложения.tryFrom(int|string): ?self
возьмет скаляр и вернет соответствующий Enum Case. Если он не найден, он вернетсяnull
. Это в основном полезно в тех случаях, когда входной скаляр не является доверенным, а вызывающая сторона хочет реализовать собственную обработку ошибок или логику значений по умолчанию.
Методы from()
и tryFrom()
следуют стандартным правилам слабой/сильной типизации. В режиме слабой типизации допустима передача целого числа или строки, и система соответствующим образом принудит значение. Передача поплавка также будет работать и будет принудительной. В режиме строгой типизации передача целого числа в from()
перечисление со строковой поддержкой (или наоборот) приведет к ошибке TypeError , как и число с плавающей запятой при любых обстоятельствах. Все остальные типы параметров вызовут ошибку TypeError в обоих режимах.
<?php
$record = get_stuff_from_database($id);
print $record['suit'];
$suit = Suit::from($record['suit']);
// Invalid data throws a ValueError: "X" is not a valid scalar value for enum "Suit"
print $suit->value;
$suit = Suit::tryFrom('A') ?? Suit::Spades;
// Invalid data returns null, so Suit::Spades is used instead.
print $suit->value;
?>
Ручное определение метода from()
or tryFrom()
для Backed Enum приведет к фатальной ошибке.
0 комментариев