Protocolos com Elixir
Digamos que você precisa implementar uma função que será responsável por recuperar o primeiro elemento de uma lista.
Teríamos algo mais ou menos assim:
defmodule MyList do
def first_item([item | _list]), do: item
end
IEx의 예를 사용하여 다음 기능을 시각화할 수 있습니다.
iex> my_list = [1, 2, 3, 4, 5, 6, 7]
[1, 2, 3, 4, 5, 6, 7]
iex> MyList.first_item(my_list)
1
Uma vez que criamos este modulo
MyList
e definimos a função para receber uma lista como paraâmetro através de pattern matching, a sua implementação fica limitada a somente listas não-vazias.O uso de outro tipo de dado como argumento geraria o seguinte erro:
iex> MyList.first_item(%{t: 2, b: 3})
** (FunctionClauseError) no function clause matching in MyList.first_item/1
Podemos resolver esse problema de duas maneiras, onde uma delas seria implementar uma nova função com um guard que cumpra os requisitos para Maps:
defmodule MyList do
def first_item([item | _list]), do: item
def first_item(map) when is_map(map) do
map
|> Enum.to_list()
|> List.first()
end
end
E dessa forma seria possível utilizar maps e listas como argumentos, 예:
iex> list = [1,2,3,4,5,6,7,8,9]
[1, 2, 3, 4, 5, 6, 7, 8, 9]
iex> map = %{a: 1, b: 2}
%{a: 1, b: 2}
iex> MyList.first_item(list)
1
iex> MyList.first_item(map)
{:a, 1}
Enquanto isso, a segunda opção para resolver este problema seria implementar um protocolo para essa função e garantir que esse protocolo funcione para as seguintes implementações: [Lista, Map]
Mas como fazemos isso?
프로토콜 및 구현
Fazendo uma breve analogia a linguagens OO (Orientada a Objetos), podemos ver o Protocolo em si como uma Interface, onde iremos definir a assinatura de um método, e as implementações como o famoso @override que usamos para dizer que queremos sobrescrever a implementação de estamos 구현에 대한 인터페이스의 기능을 결정합니다.
A definição de protocolos é feita através da estruturadefprotocol
, 다음 형식:
defprotocol MyList do
def first_item(value)
end
Não precisamos dizer como a função first_item/1
irá funcionar, basta indicar que estamos criando esse protocolo e que ele precisa possuir as devidas implementações para funcionar de acordo com o esperado.
Agora vamos fazer as implementações usandodefimpl
para o nosso caso de aceitar Listas e Maps como argumentos:
defimpl MyList, for: List do
def first_item([item | _list]), do: item
end
defimpl MyList, for: Map do
def first_item(map) do
map
|> Enum.to_list()
|> List.first()
end
end
결론
Com Protocolos nós podemos definir diferentes tipos de comportamentos para uma determinada função, semper se baseando no tipo de dado que queremos processar.
Um bom exemplo de cenário real para isso é o próprio Jason que usamos para transformar as respostas da nossa aplicação web.
O mesmo possui um protocolo chamadoJason.Encoder , 인코딩 방법에 대한 논쟁이 있습니다. 부분적인 Desta 인터페이스 구현은 json에 의존하는 인코딩 팁을 다른 방식으로 구현합니다.
Reference
이 문제에 관하여(Protocolos com Elixir), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다
https://dev.to/wlsf/protocolos-com-elixir-e0k
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념
(Collection and Share based on the CC Protocol.)
defprotocol MyList do
def first_item(value)
end
defimpl MyList, for: List do
def first_item([item | _list]), do: item
end
defimpl MyList, for: Map do
def first_item(map) do
map
|> Enum.to_list()
|> List.first()
end
end
Com Protocolos nós podemos definir diferentes tipos de comportamentos para uma determinada função, semper se baseando no tipo de dado que queremos processar.
Um bom exemplo de cenário real para isso é o próprio Jason que usamos para transformar as respostas da nossa aplicação web.
O mesmo possui um protocolo chamadoJason.Encoder , 인코딩 방법에 대한 논쟁이 있습니다. 부분적인 Desta 인터페이스 구현은 json에 의존하는 인코딩 팁을 다른 방식으로 구현합니다.
Reference
이 문제에 관하여(Protocolos com Elixir), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://dev.to/wlsf/protocolos-com-elixir-e0k텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)