Π’ΠΈΠΏΠΈΠ·ΠΈΡ€ΠΎΠ²Π°Π½Π½Ρ‹Π΅ пСрСчислСния

Π’Π°Ρ€ΠΈΠ°Π½Ρ‚Ρ‹ пСрСчислСний ΠΏΠΎ ΡƒΠΌΠΎΠ»Ρ‡Π°Π½ΠΈΡŽ Π½Π΅ содСрТат скалярного эквивалСнта ΠΈ относятся ΠΊ стандартным одноэлСмСнтным ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Π°ΠΌ, Π½ΠΎ Π²Π°Ρ€ΠΈΠ°Π½Ρ‚Ρ‹ пСрСчислСния часто трСбуСтся ΡΠΎΡ…Ρ€Π°Π½ΡΡ‚ΡŒ ΠΈ ΡΡ‡ΠΈΡ‚Ρ‹Π²Π°Ρ‚ΡŒ ΠΈΠ· Π±Π°Π·Ρ‹ Π΄Π°Π½Π½Ρ‹Ρ… ΠΈΠ»ΠΈ Π°Π½Π°Π»ΠΎΠ³ΠΈΡ‡Π½ΠΎΠ³ΠΎ Ρ…Ρ€Π°Π½ΠΈΠ»ΠΈΡ‰Π° Π΄Π°Π½Π½Ρ‹Ρ…, поэтому ΠΏΠΎΠ»Π΅Π·Π½ΠΎ ΡƒΠΊΠ°Π·Ρ‹Π²Π°Ρ‚ΡŒ для пСрСчислСния встроСнный скалярный β€” ΠΈ поэтому Ρ‚Ρ€ΠΈΠ²ΠΈΠ°Π»ΡŒΠ½ΠΎ сСриализуСмый β€” эквивалСнт, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ ΠΎΠΏΡ€Π΅Π΄Π΅Π»ΠΈΠ»ΠΈ Π²Π½ΡƒΡ‚Ρ€ΠΈ.

Бкалярный эквивалСнт пСрСчислСний ΠΎΠΏΡ€Π΅Π΄Π΅Π»ΡΡŽΡ‚ ΡΠ»Π΅Π΄ΡƒΡŽΡ‰ΠΈΠΌ синтаксисом:

<?php

enum Suit: string
{
case
Hearts = 'H';
case
Diamonds = 'D';
case
Clubs = 'C';
case
Spades = 'S';
}

Π’Π°Ρ€ΠΈΠ°Π½Ρ‚ со скалярным эквивалСнтом называСтся Ρ‚ΠΈΠΏΠΈΠ·ΠΈΡ€ΠΎΠ²Π°Π½Π½Ρ‹ΠΌ (Π°Π½Π³Π». Backed Case), ΠΏΠΎΡΠΊΠΎΠ»ΡŒΠΊΡƒ «поддСрТиваСтся» ΡƒΠΏΡ€ΠΎΡ‰Ρ‘Π½Π½Ρ‹ΠΌ Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ΠΌ. ΠŸΠ΅Ρ€Π΅Ρ‡ΠΈΡΠ»Π΅Π½ΠΈΠ΅ с Ρ‚ΠΈΠΏΠΈΠ·ΠΈΡ€ΠΎΠ²Π°Π½Π½Ρ‹ΠΌΠΈ Π²Π°Ρ€ΠΈΠ°Π½Ρ‚Π°ΠΌΠΈ называСтся Β«Ρ‚ΠΈΠΏΠΈΠ·ΠΈΡ€ΠΎΠ²Π°Π½Π½Ρ‹ΠΌ пСрСчислСниСм» (Π°Π½Π³Π». Backed Enum). Π’ΠΈΠΏΠΈΠ·ΠΈΡ€ΠΎΠ²Π°Π½Π½ΠΎΠ΅ пСрСчислСниС допускаСт Ρ‚ΠΎΠ»ΡŒΠΊΠΎ Ρ‚ΠΈΠΏΠΈΠ·ΠΈΡ€ΠΎΠ²Π°Π½Π½Ρ‹Π΅ Π²Π°Ρ€ΠΈΠ°Π½Ρ‚Ρ‹, Π° чистоС пСрСчислСниС β€” Ρ‚ΠΎΠ»ΡŒΠΊΠΎ чистыС.

ΠŸΠ΅Ρ€Π΅Ρ‡ΠΈΡΠ»Π΅Π½ΠΈΡ Π΄ΠΎΠΏΡƒΡΠΊΠ°ΡŽΡ‚ ΠΏΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΊΡƒ СдинствСнным Ρ‚ΠΈΠΏΠΎΠΌ β€” int ΠΈΠ»ΠΈ string, поэтому Ρ‚ΠΈΠΏΡ‹ нСльзя ΠΎΠ±ΡŠΠ΅Π΄ΠΈΠ½ΡΡ‚ΡŒ: int|string. Для ΠΊΠ°ΠΆΠ΄ΠΎΠ³ΠΎ Π²Π°Ρ€ΠΈΠ°Π½Ρ‚Π° Ρ‚ΠΈΠΏΠΈΠ·ΠΈΡ€ΠΎΠ²Π°Π½Π½ΠΎΠ³ΠΎ пСрСчислСния потрСбуСтся явно ΠΎΠΏΡ€Π΅Π΄Π΅Π»ΠΈΡ‚ΡŒ ΡƒΠ½ΠΈΠΊΠ°Π»ΡŒΠ½Ρ‹ΠΉ скалярный эквивалСнт. ΠŸΠ΅Ρ€Π΅Ρ‡ΠΈΡΠ»Π΅Π½ΠΈΠ΅ Π½Π΅ Π³Π΅Π½Π΅Ρ€ΠΈΡ€ΡƒΠ΅Ρ‚ Π²Π°Ρ€ΠΈΠ°Π½Ρ‚Π°ΠΌ скалярныС эквивалСнты Π½Π°ΠΏΠΎΠ΄ΠΎΠ±ΠΈΠ΅ ΠΏΠΎΡΠ»Π΅Π΄ΠΎΠ²Π°Ρ‚Π΅Π»ΡŒΠ½Ρ‹Ρ… Ρ†Π΅Π»Ρ‹Ρ… чисСл автоматичСски. PHP ΠΏΡ€ΠΎΠ²Π΅Ρ€ΠΈΡ‚ ΡƒΠ½ΠΈΠΊΠ°Π»ΡŒΠ½ΠΎΡΡ‚ΡŒ скалярных Π·Π½Π°Ρ‡Π΅Π½ΠΈΠΉ Ρ‚ΠΈΠΏΠΈΠ·ΠΈΡ€ΠΎΠ²Π°Π½Π½Ρ‹Ρ… Π²Π°Ρ€ΠΈΠ°Π½Ρ‚ΠΎΠ² пСрСчислСния, поэтому Π΄Π²ΡƒΠΌ Π²Π°Ρ€ΠΈΠ°Π½Ρ‚Π°ΠΌ Ρ‚ΠΈΠΏΠΈΠ·ΠΈΡ€ΠΎΠ²Π°Π½Π½ΠΎΠ³ΠΎ пСрСчислСния нСльзя ΠΏΡ€ΠΈΡΠ²Π°ΠΈΠ²Π°Ρ‚ΡŒ ΠΎΠ΄ΠΈΠ½ ΠΈ Ρ‚ΠΎΡ‚ ΠΆΠ΅ скалярный эквивалСнт. ΠŸΡ€ΠΈ этом константам Ρ€Π°Π·Ρ€Π΅ΡˆΠ°Π΅Ρ‚ΡΡ ΡΡΡ‹Π»Π°Ρ‚ΡŒΡΡ Π½Π° Π²Π°Ρ€ΠΈΠ°Π½Ρ‚Ρ‹ пСрСчислСния, Ρ‡Ρ‚ΠΎ фактичСски создаёт псСвдоним Π²Π°Ρ€ΠΈΠ°Π½Ρ‚Π°. Π‘ΠΌΠΎΡ‚Ρ€ΠΈΡ‚Π΅ Π³Π»Π°Π²Ρƒ Β«ΠšΠΎΠ½ΡΡ‚Π°Π½Ρ‚Ρ‹ пСрСчислСний».

Π­ΠΊΠ²ΠΈΠ²Π°Π»Π΅Π½Ρ‚Π½Ρ‹Π΅ значСния для Π²Π°Ρ€ΠΈΠ°Π½Ρ‚ΠΎΠ² пСрСчислСния ΡƒΡΡ‚Π°Π½Π°Π²Π»ΠΈΠ²Π°ΡŽΡ‚ΡΡ ΠΊΠ°ΠΊ константныС скалярныС выраТСния. Π”ΠΎ PHP 8.2.0 Π²Π°Ρ€ΠΈΠ°Π½Ρ‚Ρ‹ пСрСчислСний ΠΏΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΈΠ²Π°Π»ΠΈ Ρ‚ΠΎΠ»ΡŒΠΊΠΎ Π»ΠΈΡ‚Π΅Ρ€Π°Π»Ρ‹ ΠΈΠ»ΠΈ Π»ΠΈΡ‚Π΅Ρ€Π°Π»ΡŒΠ½Ρ‹Π΅ выраТСния. ΠšΠΎΠ½ΡΡ‚Π°Π½Ρ‚Ρ‹ ΠΈ константныС выраТСния Π½Π΅ ΠΏΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΈΠ²Π°Π»ΠΈΡΡŒ. ΠŸΠΎΡΡ‚ΠΎΠΌΡƒ выраТСния Π½Π°ΠΏΠΎΠ΄ΠΎΠ±ΠΈΠ΅ 1 + 1 Ρ€Π°Π±ΠΎΡ‚Π°Π»ΠΈ, Π° выраТСния 1 + SOME_CONST Π²Ρ‹Π·Ρ‹Π²Π°Π»ΠΈ Ρ„Π°Ρ‚Π°Π»ΡŒΠ½ΡƒΡŽ ΠΎΡˆΠΈΠ±ΠΊΡƒ.

Π£ Ρ‚ΠΈΠΏΠΈΠ·ΠΈΡ€ΠΎΠ²Π°Π½Π½Ρ‹Ρ… Π²Π°Ρ€ΠΈΠ°Π½Ρ‚ΠΎΠ² Π΅ΡΡ‚ΡŒ Π΄ΠΎΠΏΠΎΠ»Π½ΠΈΡ‚Π΅Π»ΡŒΠ½ΠΎΠ΅ доступноС Ρ‚ΠΎΠ»ΡŒΠΊΠΎ для чтСния свойство value β€” это Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅, Π·Π°Π΄Π°Π½Π½ΠΎΠ΅ Π² ΠΎΠΏΡ€Π΅Π΄Π΅Π»Π΅Π½ΠΈΠΈ Π²Π°Ρ€ΠΈΠ°Π½Ρ‚Π°.

<?php

enum Suit: string
{
case
Hearts = 'H';
case
Diamonds = 'D';
case
Clubs = 'C';
case
Spades = 'S';
}

print
Suit::Clubs->value;
// ΠšΠΎΠ½ΡΡ‚Ρ€ΡƒΠΊΡ†ΠΈΡ Π²Ρ‹Π²Π΅Π΄Π΅Ρ‚ "C"

ΠŸΠ΅Ρ€Π΅ΠΌΠ΅Π½Π½ΡƒΡŽ нСльзя Π½Π°Π·Π½Π°Ρ‡Π°Ρ‚ΡŒ ΠΊΠ°ΠΊ ссылку Π½Π° свойство value, Ρ‡Ρ‚ΠΎΠ±Ρ‹ свойство ΠΎΡΡ‚Π°Π²Π°Π»ΠΎΡΡŒ доступным Ρ‚ΠΎΠ»ΡŒΠΊΠΎ для чтСния. ΠŸΠΎΡΡ‚ΠΎΠΌΡƒ ΡΠ»Π΅Π΄ΡƒΡŽΡ‰ΠΈΠΉ ΠΊΠΎΠ΄ выдаст ΠΎΡˆΠΈΠ±ΠΊΡƒ:

<?php

enum Suit: string
{
case
Hearts = 'H';
case
Diamonds = 'D';
case
Clubs = 'C';
case
Spades = 'S';
}

$suit = Suit::Clubs;
$ref = &$suit->value;
// Fatal Error: Cannot indirectly modify readonly property Suit::$value

Π’ΠΈΠΏΠΈΠ·ΠΈΡ€ΠΎΠ²Π°Π½Π½Ρ‹Π΅ пСрСчислСния Ρ€Π΅Π°Π»ΠΈΠ·ΡƒΡŽΡ‚ Π²Π½ΡƒΡ‚Ρ€Π΅Π½Π½ΠΈΠΉ интСрфСйс BackedEnum, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ Π΄Π°Ρ‘Ρ‚ Π΄Π²Π° Π΄ΠΎΠΏΠΎΠ»Π½ΠΈΡ‚Π΅Π»ΡŒΠ½Ρ‹Ρ… ΠΌΠ΅Ρ‚ΠΎΠ΄Π°:

  • from(int|string): self Π²ΠΎΠ·ΡŒΠΌΡ‘Ρ‚ скаляр ΠΈ Π²Π΅Ρ€Π½Ρ‘Ρ‚ Π²Π°Ρ€ΠΈΠ°Π½Ρ‚ пСрСчислСния, ΠΊΠΎΡ‚ΠΎΡ€ΠΎΠΌΡƒ ΠΎΠ½ ΠΏΡ€ΠΈΠ½Π°Π΄Π»Π΅ΠΆΠΈΡ‚. Если Π²Π°Ρ€ΠΈΠ°Π½Ρ‚, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ соотвСтствуСт Π²Π°Ρ€ΠΈΠ°Π½Ρ‚Ρƒ пСрСчислСния, Π½Π΅ Π½Π°ΠΉΠ΄Π΅Π½, ΠΌΠ΅Ρ‚ΠΎΠ΄ выбросит ΠΈΡΠΊΠ»ΡŽΡ‡Π΅Π½ΠΈΠ΅ ValueError. Π­Ρ‚ΠΎ Π² основном ΠΏΠΎΠ»Π΅Π·Π½ΠΎ Ρ‚ΠΎΠ³Π΄Π°, ΠΊΠΎΠ³Π΄Π° Π²Ρ…ΠΎΠ΄Π½ΠΎΠΉ скаляр Π½Π°Π΄Ρ‘ΠΆΠ΅Π½, Π° отсутствиС значСния пСрСчислСния Π½Π°Π΄ΠΎ Ρ€Π°ΡΡΠΌΠ°Ρ‚Ρ€ΠΈΠ²Π°Ρ‚ΡŒ ΠΊΠ°ΠΊ ΠΎΡˆΠΈΠ±ΠΊΡƒ, ΠΎΡΡ‚Π°Π½Π°Π²Π»ΠΈΠ²Π°ΡŽΡ‰ΡƒΡŽ ΠΏΡ€ΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠ΅.
  • tryFrom(int|string): ?self Π²ΠΎΠ·ΡŒΠΌΡ‘Ρ‚ скаляр ΠΈ Π²Π΅Ρ€Π½Ρ‘Ρ‚ Π²Π°Ρ€ΠΈΠ°Π½Ρ‚ пСрСчислСния, ΠΊΠΎΡ‚ΠΎΡ€ΠΎΠΌΡƒ ΠΎΠ½ ΠΏΡ€ΠΈΠ½Π°Π΄Π»Π΅ΠΆΠΈΡ‚. Если Π²Π°Ρ€ΠΈΠ°Π½Ρ‚, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ соотвСтствуСт Π²Π°Ρ€ΠΈΠ°Π½Ρ‚Ρƒ пСрСчислСния, Π½Π΅ Π½Π°ΠΉΠ΄Π΅Π½, ΠΌΠ΅Ρ‚ΠΎΠ΄ Π²Π΅Ρ€Π½Ρ‘Ρ‚ null. Π­Ρ‚ΠΎ Π² основном ΠΏΠΎΠ»Π΅Π·Π½ΠΎ Ρ‚ΠΎΠ³Π΄Π°, ΠΊΠΎΠ³Π΄Π° Π²Ρ…ΠΎΠ΄Π½ΠΎΠΉ скаляр Π½Π΅Π½Π°Π΄Ρ‘ΠΆΠ΅Π½ ΠΈ Π²Ρ‹Π·Ρ‹Π²Π°ΡŽΡ‰Π°Ρ функция Ρ…ΠΎΡ‡Π΅Ρ‚ Ρ€Π΅Π°Π»ΠΈΠ·ΠΎΠ²Π°Ρ‚ΡŒ свою ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚ΠΊΡƒ ошибок ΠΈΠ»ΠΈ Π»ΠΎΠ³ΠΈΠΊΡƒ значСния ΠΏΠΎ ΡƒΠΌΠΎΠ»Ρ‡Π°Π½ΠΈΡŽ.

ΠœΠ΅Ρ‚ΠΎΠ΄Ρ‹ from() ΠΈ tryFrom() ΡΠ»Π΅Π΄ΡƒΡŽΡ‚ стандартным ΠΏΡ€Π°Π²ΠΈΠ»Π°ΠΌ слабой/строгой Ρ‚ΠΈΠΏΠΈΠ·Π°Ρ†ΠΈΠΈ. Π’ Ρ€Π΅ΠΆΠΈΠΌΠ΅ слабой Ρ‚ΠΈΠΏΠΈΠ·Π°Ρ†ΠΈΠΈ допустима ΠΏΠ΅Ρ€Π΅Π΄Π°Ρ‡Π° Ρ†Π΅Π»ΠΎΠ³ΠΎ числа ΠΈΠ»ΠΈ строки, систСма ΠΏΡ€ΠΈΠ²Π΅Π΄Ρ‘Ρ‚ Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ ΠΈ Π½Π°ΠΉΠ΄Ρ‘Ρ‚ Π²Π°Ρ€ΠΈΠ°Π½Ρ‚, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ Π΅ΠΌΡƒ соотвСтствуСт. ΠŸΠ΅Ρ€Π΅Π΄Π°Ρ‡Π° числа с ΠΏΠ»Π°Π²Π°ΡŽΡ‰Π΅ΠΉ Ρ‚ΠΎΡ‡ΠΊΠΎΠΉ Ρ‚Π°ΠΊΠΆΠ΅ Π±ΡƒΠ΄Π΅Ρ‚ Ρ€Π°Π±ΠΎΡ‚Π°Ρ‚ΡŒ ΠΈ ΠΏΡ€ΠΈΠ²ΠΎΠ΄ΠΈΡ‚ΡŒΡΡ. Π’ Ρ€Π΅ΠΆΠΈΠΌΠ΅ строгой Ρ‚ΠΈΠΏΠΈΠ·Π°Ρ†ΠΈΠΈ ΠΏΠ΅Ρ€Π΅Π΄Π°Ρ‡Π° Ρ†Π΅Π»ΠΎΠ³ΠΎ числа Π² ΠΌΠ΅Ρ‚ΠΎΠ΄ from() Π² пСрСчислСнии со строковой Ρ‚ΠΈΠΏΠΈΠ·Π°Ρ†ΠΈΠ΅ΠΉ (ΠΈΠ»ΠΈ Π½Π°ΠΎΠ±ΠΎΡ€ΠΎΡ‚) Π² любом случаС ΠΏΡ€ΠΈΠ²Π΅Π΄Ρ‘Ρ‚ ΠΊ ΠΈΡΠΊΠ»ΡŽΡ‡Π΅Π½ΠΈΡŽ TypeError, ΠΊΠ°ΠΊ ΠΈ ΠΏΠ΅Ρ€Π΅Π΄Π°Ρ‡Π° числа с ΠΏΠ»Π°Π²Π°ΡŽΡ‰Π΅ΠΉ Ρ‚ΠΎΡ‡ΠΊΠΎΠΉ. ВсС ΠΎΡΡ‚Π°Π»ΡŒΠ½Ρ‹Π΅ Ρ‚ΠΈΠΏΡ‹ ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€ΠΎΠ² выбросят ΠΈΡΠΊΠ»ΡŽΡ‡Π΅Π½ΠΈΠ΅ TypeError Π² ΠΎΠ±ΠΎΠΈΡ… Ρ€Π΅ΠΆΠΈΠΌΠ°Ρ….

<?php

enum Suit: string
{
case
Hearts = 'H';
case
Diamonds = 'D';
case
Clubs = 'C';
case
Spades = 'S';
}

function
get_stuff_from_database($id)
{
return [
'suit' => 'S',
];
}

$record = get_stuff_from_database(42);
print
$record['suit'] . "\n";

$suit = Suit::tryFrom('A') ?? Suit::Spades;
// НСдопустимыС Π΄Π°Π½Π½Ρ‹Π΅ Π²ΠΎΠ·Π²Ρ€Π°Ρ‰Π°ΡŽΡ‚ Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ null, поэтому вмСсто этого Π±ΡƒΠ΄Π΅Ρ‚ использовано Suit::Spades.
print $suit->value . "\n";

$suit = Suit::from('X');
// НСдопустимыС Π΄Π°Π½Π½Ρ‹Π΅ выбросят ΠΈΡΠΊΠ»ΡŽΡ‡Π΅Π½ΠΈΠ΅ ValueError: "X" is not a valid backing scalar value for enum Suit
print $suit->value . "\n";

Π ΡƒΡ‡Π½ΠΎΠ΅ ΠΎΠΏΡ€Π΅Π΄Π΅Π»Π΅Π½ΠΈΠ΅ ΠΌΠ΅Ρ‚ΠΎΠ΄Π° from() ΠΈΠ»ΠΈ tryFrom() Π² Ρ‚ΠΈΠΏΠΈΠ·ΠΈΡ€ΠΎΠ²Π°Π½Π½Ρ‹Ρ… пСрСчислСниях ΠΏΡ€ΠΈΠ²Π΅Π΄Ρ‘Ρ‚ ΠΊ Ρ„Π°Ρ‚Π°Π»ΡŒΠ½ΠΎΠΉ ошибкС.

οΌ‹Π”ΠΎΠ±Π°Π²ΠΈΡ‚ΡŒ

ΠŸΡ€ΠΈΠΌΠ΅Ρ‡Π°Π½ΠΈΡ ΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚Π΅Π»Π΅ΠΉ

ΠŸΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚Π΅Π»ΠΈ Π΅Ρ‰Ρ‘ Π½Π΅ добавляли примСчания для страницы