Elixir - Protocolos
Os protocolos são um mecanismo para atingir polimorfismo no Elixir. O despacho em um protocolo está disponível para qualquer tipo de dados, desde que implemente o protocolo.
Vamos considerar um exemplo de uso de protocolos. Usamos uma função chamadato_stringnos capítulos anteriores para converter de outros tipos para o tipo string. Este é realmente um protocolo. Ele atua de acordo com a entrada fornecida sem produzir um erro. Pode parecer que estamos discutindo funções de correspondência de padrões, mas à medida que avançamos, fica diferente.
Considere o exemplo a seguir para entender melhor o mecanismo do protocolo.
Vamos criar um protocolo que mostrará se a entrada fornecida está vazia ou não. Vamos chamar este protocoloblank?.
Definindo um Protocolo
Podemos definir um protocolo no Elixir da seguinte maneira -
defprotocol Blank do
def blank?(data)
end
Como você pode ver, não precisamos definir um corpo para a função. Se você está familiarizado com interfaces em outras linguagens de programação, pode pensar em um protocolo como essencialmente a mesma coisa.
Portanto, este Protocolo está dizendo que qualquer coisa que o implemente deve ter um empty?função, embora seja responsabilidade do implementador como a função responde. Com o protocolo definido, vamos entender como adicionar algumas implementações.
Implementando um Protocolo
Como definimos um protocolo, agora precisamos dizer a ele como lidar com as diferentes entradas que ele pode obter. Vamos continuar com o exemplo que tínhamos tomado anteriormente. Implementaremos o protocolo em branco para listas, mapas e strings. Isso mostrará se o que passamos está em branco ou não.
#Defining the protocol
defprotocol Blank do
def blank?(data)
end
#Implementing the protocol for lists
defimpl Blank, for: List do
def blank?([]), do: true
def blank?(_), do: false
end
#Implementing the protocol for strings
defimpl Blank, for: BitString do
def blank?(""), do: true
def blank?(_), do: false
end
#Implementing the protocol for maps
defimpl Blank, for: Map do
def blank?(map), do: map_size(map) == 0
end
IO.puts(Blank.blank? [])
IO.puts(Blank.blank? [:true, "Hello"])
IO.puts(Blank.blank? "")
IO.puts(Blank.blank? "Hi")
Você pode implementar seu protocolo para quantos tipos desejar, o que fizer sentido para o uso de seu protocolo. Este foi um caso de uso bastante básico de protocolos. Quando o programa acima é executado, ele produz o seguinte resultado -
true
false
true
false
Note - Se você usar isso para qualquer tipo diferente daqueles para os quais definiu o protocolo, ocorrerá um erro.