Enum

Enum

Один з багатьох доступних типів у програмуванні та, з недавнього часу, в PHP. Пропоную спочатку розібратись що таке Enum, а потім, як працювати з Enum у PHP.


Що таке Enum?

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

Уперше, цей тип було запропоновано в C і використано в С та С++. Ці мови програмування більш низькорівневі ніж сучасні PHP, JS та інші, тож можна сказати що проблеми які вирішували тоді enum не такі актуальні ніж проблеми які вони вирішують зараз. Чудовий приклад якісно сформованої концепції.

Чи є альтернативи для Enum?

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

Ще один трюк для розв’язання проблеми – створення класу з константами, які б могли зберігати в собі скалярні значення. Тоді доступ до таких квазі-перечислень буде більше зручним ніж до аналогічного рішення, але з використанням масивів.

В будь-якому випадку, варто звернути увагу на ті проблеми які обʼєднують ці аналогії:

  1. У таких квазі-перечислення можна помістити будь-який скалярний тип. Тобто, нема гарантій що наступна константа або елемент масиву будуть одного типу.
  2. Можна помістити не скалярне значення. Enum, це насамперед тип, який дозволяє створити закритий набір даних. Іншими словами, значення будь-якого елемента з набору можуть бути лише простими, щоб не робити тип надто складним, який би виконував більше, ніж в нього закладено.
  3. Усі елементи не обʼєднуються в один тип. Тобто, умовно кажучи, коли ми хочемо підкреслити, що деяка функція, як результат, повертає певний HTTP код, то ми не зможемо вказати можливий діапазон (набір) для HTTP кодів з викорисатнням return type.
    Те ж саме і з аргументами. Наприклад, ми захочемо щоб функція отримувала назву місяця і повертали кількість днів у цьому місяці, в такому випадку нам буде нічим гарантувати що місяць “один із”.

Тепер, звертаючи увагу на аналоги і проблеми аналогів пропоную розглянути на прикладі PHP як Enum буде вирішувати недоліки викладені вище.


Enum в PHP

Починаючи з версії 8.1 в PHP додано тип Enum. За видом він може бути Unit Enum або Backed Enum.

Як саме Enum вирішує описані вище проблеми?

  1. У таких квазі-перечислення можна помістити будь-який скалярний тип. Тобто, нема гарантій що наступна константа або елемент масиву будуть одного типу.

    Тип даних Enum в PHP як ідентифікатор використовує лише тип String. Як значення (value), якщо використовується Backed Enum, може бути лише один і той же тип який вказується під час опису перерахування.

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

    Backed Enum – тип перерахування, який дозволяє містити деяке значення поряд з ідентифікатором. Це значення може бути лише скалярним і однотипним.

  3. Усі елементи не обʼєднуються в один тип. Тобто, умовно кажучи, коли ми хочемо підкреслити, що деяка функція, як результат, повертає певний HTTP код, то ми не зможемо вказати можливий діапазон (набір) для HTTP кодів з викорисатнням return type.
    Те ж саме і з аргументами. Наприклад, ми захочемо щоб функція отримувала назву місяця і повертали кількість днів у цьому місяці, в такому випадку нам буде нічим гарантувати що місяць “один із”.

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

    function debit(Payments $payment_type)
    

    Або, якщо використання аналогічного опису для результату функції :

    function credit(int $amount): Payments
    

    1. Unit Enum

      Це одиничні перерахування. Кожен елемент такого набору – case, це singleton обʼєкт.

       Оголошення

      enum Friends
      {
      case Olha;
      case Alex;
      case Polina;
      case Vadim
      }
      

      Використання

      function sendBill(Friends $person): bool
      {
      // Якщо рахунок спробують надіслати використовуючи `$person` не зі списку друзів - буде помилка!
      }
      
      $notify->target = Friends::Vadim;
      // Стан класу `$target` буде обʼєкт singleton - Vadim із перерахування Friends
      

      Це приклад класичного або ж “простого” використання перерахувань


      Backed Enum

      На відмінність від одиничних перерахувань, з’являється можливість додати скалярне значення для case.

      Оголошення

      enum Friends: string
      {
          case Olha = 'pink';
          case Alex = 'green'; 
          case Polina = 'pink';
          case Vadim = 'yellow'
      }
      

      Тип важливо вказувати, щоб не отримати помилку!

      Використання

      echo 'Alex like color - '.Friends::Alex; 
      //Alex like color - green.
      

Enum

Enum

Один з багатьох доступних типів у програмуванні та, з недавнього часу, в PHP. Пропоную спочатку розібратись що таке Enum, а потім, як працювати з Enum у PHP.


Що таке Enum?

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

Уперше, цей тип було запропоновано в C і використано в С та С++. Ці мови програмування більш низькорівневі ніж сучасні PHP, JS та інші, тож можна сказати що проблеми які вирішували тоді enum не такі актуальні ніж проблеми які вони вирішують зараз. Чудовий приклад якісно сформованої концепції.

Чи є альтернативи для Enum?

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

Ще один трюк для розв’язання проблеми – створення класу з константами, які б могли зберігати в собі скалярні значення. Тоді доступ до таких квазі-перечислень буде більше зручним ніж до аналогічного рішення, але з використанням масивів.

В будь-якому випадку, варто звернути увагу на ті проблеми які обʼєднують ці аналогії:

  1. У таких квазі-перечислення можна помістити будь-який скалярний тип. Тобто, нема гарантій що наступна константа або елемент масиву будуть одного типу.
  2. Можна помістити не скалярне значення. Enum, це насамперед тип, який дозволяє створити закритий набір даних. Іншими словами, значення будь-якого елемента з набору можуть бути лише простими, щоб не робити тип надто складним, який би виконував більше, ніж в нього закладено.
  3. Усі елементи не обʼєднуються в один тип. Тобто, умовно кажучи, коли ми хочемо підкреслити, що деяка функція, як результат, повертає певний HTTP код, то ми не зможемо вказати можливий діапазон (набір) для HTTP кодів з викорисатнням return type.
    Те ж саме і з аргументами. Наприклад, ми захочемо щоб функція отримувала назву місяця і повертали кількість днів у цьому місяці, в такому випадку нам буде нічим гарантувати що місяць “один із”.

Тепер, звертаючи увагу на аналоги і проблеми аналогів пропоную розглянути на прикладі PHP як Enum буде вирішувати недоліки викладені вище.


Enum в PHP

Починаючи з версії 8.1 в PHP додано тип Enum. За видом він може бути Unit Enum або Backed Enum.

Як саме Enum вирішує описані вище проблеми?

  1. У таких квазі-перечислення можна помістити будь-який скалярний тип. Тобто, нема гарантій що наступна константа або елемент масиву будуть одного типу.

    Тип даних Enum в PHP як ідентифікатор використовує лише тип String. Як значення (value), якщо використовується Backed Enum, може бути лише один і той же тип який вказується під час опису перерахування.

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

    Backed Enum – тип перерахування, який дозволяє містити деяке значення поряд з ідентифікатором. Це значення може бути лише скалярним і однотипним.

  3. Усі елементи не обʼєднуються в один тип. Тобто, умовно кажучи, коли ми хочемо підкреслити, що деяка функція, як результат, повертає певний HTTP код, то ми не зможемо вказати можливий діапазон (набір) для HTTP кодів з викорисатнням return type.
    Те ж саме і з аргументами. Наприклад, ми захочемо щоб функція отримувала назву місяця і повертали кількість днів у цьому місяці, в такому випадку нам буде нічим гарантувати що місяць “один із”.

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

    function debit(Payments $payment_type)
    

    Або, якщо використання аналогічного опису для результату функції :

    function credit(int $amount): Payments
    

    1. Unit Enum

      Це одиничні перерахування. Кожен елемент такого набору – case, це singleton обʼєкт.

       Оголошення

      enum Friends
      {
      case Olha;
      case Alex;
      case Polina;
      case Vadim
      }
      

      Використання

      function sendBill(Friends $person): bool
      {
      // Якщо рахунок спробують надіслати використовуючи `$person` не зі списку друзів - буде помилка!
      }
      
      $notify->target = Friends::Vadim;
      // Стан класу `$target` буде обʼєкт singleton - Vadim із перерахування Friends
      

      Це приклад класичного або ж “простого” використання перерахувань


      Backed Enum

      На відмінність від одиничних перерахувань, з’являється можливість додати скалярне значення для case.

      Оголошення

      enum Friends: string
      {
          case Olha = 'pink';
          case Alex = 'green'; 
          case Polina = 'pink';
          case Vadim = 'yellow'
      }
      

      Тип важливо вказувати, щоб не отримати помилку!

      Використання

      echo 'Alex like color - '.Friends::Alex; 
      //Alex like color - green.