March 17, 2021

← Home

Entendendo Pattern Matching no elixir

Neste artigo irei explicar um pouco sobre o 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

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>)

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 

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

defmodule PatternMatchingArtigo do

end

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

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

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

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

iex -S mix

iex> PatternMatchingArtigo.count_length([1,2,3])

vai retornar:

1
[2,3]

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

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

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)

Ele vai retornar:

1

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

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

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

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

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!


Profile

Written by João Pedro
Web developer and linux student