Протоколи дають змогу досягти поліморфізму в Elixir, коли ми хочемо, щоб поведінка змінювалася залежно від типу даних.
Протоколи визначаються за допомогою defprotocol і містять один або кілька заголовків функцій.
defprotocol Reversible do
def reverse(term)
end
Протоколи можна реалізувати за допомогою defimpl.
defimpl Reversible, for: List do
def reverse(term) do
Enum.reverse(term)
end
end
Протокол можна реалізувати для будь-якого наявного типу даних Elixir або для структури.
Коли викликають функцію протоколу, відповідну реалізацію автоматично обирають на основі типу першого аргументу.
Ми розробляємо власну рольову відеогру. У нашій грі є персонажі та предмети. Одна з багатьох дій, які можна виконати з предметом, - змусити персонажа зʼїсти його.
Не всі предмети їстівні, і не всі їстівні предмети однаково впливають на персонажа. Деякі предмети, коли їх зʼїсти, перетворюються на інший предмет (наприклад, якщо зʼїсти яблуко, залишається огризок).
Щоб забезпечити всю цю гнучкість, ми вирішили створити протокол Edible, який можуть реалізувати деякі з предметів.
Створіть протокол RPG.Edible. Протокол має одну функцію - eat. Функція eat приймає предмет і персонажа та повертає побічний продукт і персонажа.
Реалізуйте протокол RPG.Edible для предмета RPG.LoafOfBread. Коли його зʼїсти, буханець хліба дає персонажу 5 одиниць здоровʼя і не має побічного продукту.
RPG.Edible.eat(%RPG.LoafOfBread{}, %RPG.Character{health: 31})
# => {nil, %RPG.Character{health: 36, mana: 0}}
Реалізуйте протокол RPG.Edible для предмета RPG.ManaPotion. Коли його зʼїсти, зілля мани дає персонажу стільки одиниць мани, скільки становить сила зілля, і створює порожню пляшечку.
RPG.Edible.eat(%RPG.ManaPotion{strength: 13}, %RPG.Character{mana: 50})
# => {%RPG.EmptyBottle{}, %RPG.Character{health: 100, mana: 63}}
Реалізуйте протокол RPG.Edible для предмета RPG.Poison. Коли його зʼїсти, отрута забирає в персонажа всі одиниці здоровʼя і створює порожню пляшечку.
RPG.Edible.eat(%RPG.Poison{}, %RPG.Character{health: 3000})
# => {%RPG.EmptyBottle{}, %RPG.Character{health: 0, mana: 0}}
Зареєструйтеся на Exercism, щоб вивчати й опановувати Elixir, а також 58 концепцій168 вправ та справжнє наставництво від людей, і все це безкоштовно.