Protocolos são um mecanismo para alcançar polimorfismo em Elixir quando você quer que o comportamento varie de acordo com o tipo de dado.
Protocolos são definidos com defprotocol e contêm uma ou mais assinaturas de função.
defprotocol Reversible do
def reverse(term)
end
Protocolos podem ser implementados com defimpl.
defimpl Reversible, for: List do
def reverse(term) do
Enum.reverse(term)
end
end
Um protocolo pode ser implementado para qualquer tipo de dado existente do Elixir ou para um struct.
Quando uma função de protocolo é chamada, a implementação apropriada é escolhida automaticamente com base no tipo do primeiro argumento.
Você está desenvolvendo seu próprio videogame de RPG. No seu jogo, existem personagens e itens. Uma das muitas ações que você pode fazer com um item é fazer um personagem comê-lo.
Nem todos os itens são comestíveis, e nem todos os itens comestíveis têm os mesmos efeitos sobre o personagem. Alguns itens, quando comidos, se transformam em um item diferente (por exemplo, se você comer uma maçã, sobra o caroço).
Para permitir toda essa flexibilidade, você decidiu criar um protocolo Edible que alguns dos itens podem implementar.
Crie o protocolo RPG.Edible. O protocolo tem uma função: eat. A função eat aceita um item e um personagem e retorna um subproduto e um personagem.
Implemente o protocolo RPG.Edible para o item RPG.LoafOfBread. Quando comido, um pão dá ao personagem 5 pontos de vida e não produz subproduto.
RPG.Edible.eat(%RPG.LoafOfBread{}, %RPG.Character{health: 31})
# => {nil, %RPG.Character{health: 36, mana: 0}}
Implemente o protocolo RPG.Edible para o item RPG.ManaPotion. Quando ingerida, uma poção de mana dá ao personagem tantos pontos de mana quanto a força da poção, e produz uma garrafa vazia.
RPG.Edible.eat(%RPG.ManaPotion{strength: 13}, %RPG.Character{mana: 50})
# => {%RPG.EmptyBottle{}, %RPG.Character{health: 100, mana: 63}}
Implemente o protocolo RPG.Edible para o item RPG.Poison. Quando ingerido, um veneno tira todos os pontos de vida do personagem e produz uma garrafa vazia.
RPG.Edible.eat(%RPG.Poison{}, %RPG.Character{health: 3000})
# => {%RPG.EmptyBottle{}, %RPG.Character{health: 0, mana: 0}}
Crie sua conta no Exercism para aprender e dominar Elixir com 58 conceitos168 exercícios e mentoria humana de verdade, tudo de graça.