DEV Community

Cover image for [PT-BR] Pattern Matching no Elixir
João Pedro Resende
João Pedro Resende

Posted on • Edited on

[PT-BR] Pattern Matching no Elixir

Eae galera! Neste artigo irei explicar um pouco sobre o pattern matching no elixir!

Afinal o que é o pattern matching?

O pattern matching é uma forma de desestruturar facilmente os tipos de dados, tuplas e listas. Támbem é um dos fundamentos da recursividade no Elixir.

Váriaveis no Elixir

Ao longo do artigo iremos ver sobre o pattern matching e para entender os códigos escritos entenda um pouco sobre as váriaveis no elixir.

No elixir as variaveis não são atribuidas por um valor.

Para explicar melhor aqui está um exemplo:

variavel = 1

Para a variavel ser igual a 1, na matemática se, por exemplo x = 1 o que o x tem que valer para ser equivalente a 1? Ele tem que ser 1

E acontece a mesma coisa no elixir, por isso as váriaveis são imutaveis.

E acabamos de ver pattern matching nas váriaveis do elixir.


Rodando projetos elixir

Para rodar o nosso projeto iremos entrar no modo interativo do elixir(mesmo ele sendo uma lang compilada, ele tem um modo interativo).

iex -S mix
Enter fullscreen mode Exit fullscreen mode

E depois

Vai digitar o nome do módulo(no nosso caso PatternMatchingArtigo) e também o nome da função que você quer executar.

iex> PatternMatchingArtigo.<nome da função>(<parametros>)
Enter fullscreen mode Exit fullscreen mode

E é só trocar esses <> pelo nome da função e os parametros.


Utilizando o pattern matching na prática!

Pré-requesitos:

Primeiro nós vamos criar o projeto em elixir com o mix:

mix new pattern_matching_artigo 
Enter fullscreen mode Exit fullscreen mode

Em lib/pattern_matching_artigo.ex,
vamos apagar todas as funções deixando apenas o defmodule

defmodule PatternMatchingArtigo do

end
Enter fullscreen mode Exit fullscreen mode

Depois de apagarmos todas as funções, vamos criar uma função chamada call() que vai ter um parametro que vai ser uma lista:

defmodule PatternMatchingArtigo do
    def call(list) do

    end
end
Enter fullscreen mode Exit fullscreen mode

No elixir não é possivel pegar o valor de uma lista com lista[1], por isso vamos ver como funciona o pattern matching com as listas.

Para percorrer a lista vamos criar uma função chamada count_length com um paremetro chamado [head | tail]:

    def count_length([head | tail]) do

    end
Enter fullscreen mode Exit fullscreen mode

O que seria esse [head | tail]?

Em elixir uma forma de pegar os elementos de uma lista é utilizando essa forma. O head é o primeiro elemento da lista, e o tail é o corpo da lista, ou seja, todos os outros elementos da lista.

Por exemplo:

    def count_length([head | tail]) do
        IO.inspect(head)

        IO.inspect(tail)
    end
Enter fullscreen mode Exit fullscreen mode

Se a gente rodar esta função passando uma lista [1,2,3]

iex -S mix

iex> PatternMatchingArtigo.count_length([1,2,3])
Enter fullscreen mode Exit fullscreen mode

vai retornar:

1
[2,3]
Enter fullscreen mode Exit fullscreen mode

Sabendo disso podemos continuar nosso projeto:

Para contar a quantidade de uma lista temos que ter um contador, então vamos passar ele como parametro:

def count_length([head | tail], count) do
    IO.inspect(head)

    IO.inspect(tail)
end
Enter fullscreen mode Exit fullscreen mode

Já que não iremos usar o head para fazer a contagem podemos colocar um _ na frente dessa váriavel. Isso indica que iremos receber essa variavel como parametro mas não vamos utiliza-lo.

E também vamos incrementar a contagem.

def count_length([_head | tail], count) do
    count = count + 1
end
Enter fullscreen mode Exit fullscreen mode

Mas como estamos atribuindo um valor ao uma váriavel, sendo que no elixir as váriaveis são imutaveis?

Na verdade não estamos reatribuindo um valor a uma variavel e sim estamos criando uma nova variavel chamada count.

Se executarmos esse código com o iex, passando como parametro o count que vai ser o número que vai iniciar a contagem da lista.

iex> PatternMatchingArtigo.count_length([1,2,3], 0)
Enter fullscreen mode Exit fullscreen mode

Ele vai retornar:

1
Enter fullscreen mode Exit fullscreen mode

Agora vamos aplicar recursividade nesta função:

def count_length([head | tail], count) do
    count = count + 1

    # Passando tail e a contagem como parametro.
    count_length(tail, count)
end
Enter fullscreen mode Exit fullscreen mode

Se rodarmos essa função novamente ele vai dar um erro que está passando uma lista vazia

Podemos resolver adicionando outra função filter_length()

def count_length([], count), do: count
Enter fullscreen mode Exit fullscreen mode

E o que esta função faz?

Esta função verifica se a lista está vazia, e se estiver vai retornar a contagem total da lista.

Caso esteja com valores nesta lista ele vai adicionar 1 na contagem e vai executar denovo a função até acabar de percorrer a lista.

E também acabamos de ver Pattern Matching com funções!

E por fim na função call(), vamos adicionar um paremetro chamado list e executar a função count_length.

def call(list) do
    count_length(list, 0)
end
Enter fullscreen mode Exit fullscreen mode

Assim, finalizamos nosso mini projeto de contar o tamanho das listas com Pattern Matching e também utilizando recursão!


O Pattern Matching funciona também com tuplas

Por exemplo:

defp print_content_file({:ok, content}), do: content

defp print_content_file({:error, reason}), do: reason
Enter fullscreen mode Exit fullscreen mode

Nesta função privada(função privada no elixir é defp e uma função pública é def) ele vai pegar uma tupla que retorna :ok, e algum conteudo e vai retornar esse conteudo.

Se retornar um erro vai retornar um erro.

E assim utilizamos pattern matching com listas, tuplas, funções e também tratamos de erros.


Caso tenha alguma duvida do código feito durante o artigo acesse o repositório que contem o projeto feito durante esse artigo.


Esse artigo foi um pouco longo mas espero que você tenha gostado!

Se gostou do artigo deixe o like, compartilhe com os amigos e comente o que achou do artigo!

Até a proxima!

Top comments (2)

Collapse
 
eduardoklosowski profile image
Eduardo Klosowski

Os conceitos de programação funcional são bastante interessantes, como a forma de usar uma lista e funções recursivas para fazer iterações no lugar de um for. Essas formas de pensar e escrever código também podem facilitar a escrita de alguns códigos, que poderiam ser mais complexos quando feitos de forma mais tradicional.

Collapse
 
jpbrab0 profile image
João Pedro Resende

Esses conceitos são bem interesantes mesmo!