Criando extension functions com Dart/Flutter

Neste artigo-tutorial vamos aprender como criar extensões personalizadas com Dart para auxiliar o desenvolvimento dos nossos apps Flutter.

Kaue Murakami
4 min readSep 17, 2022
image credit: Arathi Shankri

Você verá neste artigo :
Como criar e quando usar extension functions.

As extensões possibilitam novas funcionalidades ao nosso código. Eles são reutilizáveis ​​e eficazes. Além de ajudar a manter seu código limpo.
Muitas “funções” podem ser convertidas em extensions facilitando a manutenção e mantendo seu código mais limpo.

Vamos abordar a utilização de extension functions no contexto do Flutter, mas as mesmas práticas podem ser aplicadas em qualquer aplicação Dart.
Você pode usar o DartPad para testar a maioria das funcionalidades que aqui serão apresentadas.
Ao final vou dar um exemplo bônus interagindo com o Flutter, portanto partimos do pressuposto que você possua um experiência mínima com Flutter.

Inicialmente vamos criar nossa main no DartPad

Como exemplo criei três extensões, lembrando que são funções criadas para exemplificar o uso de extensões, não uma recomendação, então não vai sair por ai transformando tudo em extensão (っ^з^).

Extensões:

popNull

Responsável por excluir “values” e “keys” nulas de um determinado Map.

Vamos ao Dart Pad e fora do contexto da main adicione o código da extensão, se você copiou o exemplo da main, após adicionar este trecho já pode executar e verá o resultado {a: non-null, u: }.

Entendendo o código:

Inicialmente você pode notar a tipagem com a palavra reservada extension.
MapExtension é o nome que eu dei para a extensão, você pode alterar para qualquer outro valor.

on Map<dynamic, dynamic> este é o tipo que pode utilizar nossa extensão, neste caso, qualquer Map, isso não define o retorno da nossa função, mas na maioria das vezes vai ser o mesmo tipo do retorno, vamos ver isso nos próximos exemplos, mas neste caso ele também retorna um Map.

Após a definição da extensão, no seu contexto, podemos ver uma função get, como não possuimos parâmetros, podemos utilizar diretamente, e ele por si só executa a função que queremose retorna o valor que definimos, o novo valor.

Isto é útil quando você quer enviar dados para o backend e ele ainda não está preparado para lidar com valores nulos por exemplo.

  • multiReplace(Map<dynamic,dynamic>)
    -
    Responsável por fazer o replace numa string baseado em um Map, onde a “key” é o elemente a ser substituido e o “value” o valor que substituirá o valor da “key”.

Entendendo o código:

Neste exemplo temos uma extensão com parâmetros, o que se assemelha bastante a uma função, então podemos ver inicialmente como a sintaxe é mais agradavél do que se fosse uma função.
Neste caso, estamos apenas fazendo um replace comparando “key” — “value” / chave — valor.

Portanto copie esse código abaixo da extensão anterior, fora do contexto da main e execute.
Você verá o resultado '123123>DOT<123123MAIS’

  • pathAsset(path: PathType, type: ImageType)
    -
    A mais interessante, vamos utilizar ela para que, a partir do nome da imagem, consigamos retornar um Widget Image.
    Para testar essa extensão você precisará utilizar o Flutter.

Entendendo o código:

Nas explicações anteriores ainda não tinhamos nos deparado com casos em que utilizamos o objeto que recebe a extensão explicitamente, mas isso aconteceu sem que você percebece xD, pois para métodos, o this não precisa ser explicitado.

Por exemplo, quando usamos ‘string’.myExtension ou {‘k’:’a’}.myExtension, levamos esse objeto conosco pra nossa função de extensão, podendo referenciar ele como this, o prório objeto.
Portanto neste caso, this é a string com nome da nossa imagem, exemplo: image.png.

Desta vez adicionei alguns parâmetros apenas para tentar aumentar a complexidade da extensão.

Dois enums foram criados, ImageType tendo os valores assets para arquivos locais ou network para imagens da internet.

O outro é o PathType com ele, podemos separar nossas imagens por diretório app/assets , portanto podemos ter arquivos em ‘assets/images/nome.ext’ ou ‘assets/icons/nome.ext’ e esse enum nos ajudará a diferenciar, lembrando que podemos adicionar valores padrões, para que na maioria dos contextos não precisemos informar nenhum parâmetro, utilizando apenas ‘image.png’.pathAsset, isso irá nos retornar Image.asset(‘assets/image.png’)

Caso queiramos especificar diferentes uso você pode usar normalmente ‘https://………….png.pathAsset(type: ImageType.network , path: PathType.network), isso nos retornará Image.network(‘https://………….png’)

Outro fato que não havia ocorrido nos exemplos anteriores é que retornamos um tipo diferente do tipo recebido, ou seja de this.
Nesse caso estou retornando um widget, a partir de uma string, e tipos setados.

Exemplo de utilização:

Aqui possuo uma pasta project_name/assets/icons e project_name/assets/images/logo.png

Lembrando que esse arquivo, caso seja local, deve estar adicionado em seu pubspec.yaml

Fim, aqui pudemos ver a aplicação e uso de extension methods com Flutter.

Ficou alguma dúvida ? deixa nos comentários.
E siga-me no GitHub

--

--

Kaue Murakami
Kaue Murakami

Written by Kaue Murakami

Ninja in Dart - Flutter and NodeJS - JavaScript

No responses yet