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.