Às vezes, há a necessidade de definir a funcionalidade de tal forma que ela possa usar dados de qualquer tipo, sem perder a verificação de tipo como acontece usando o dinamic, nesses casos podemos utilizar o recurso de generics presente na linguagem Dart.
Neste artigo veremos como utilizar generics ou generalização no Dart, os generics servem para que você adicione mais flexibilidade ao programa. Servem, também, para garantir que os tipos dos dados com qual estamos trabalhando sejam o que esperamos.
Simplificando, os generics são uma maneira de criar métodos, funções ou classes que funcionam com uma gama de tipos de dados em vez de apenas um.
Curso Dart - Fundamentos
Conhecer o cursoComo utilizar generics no Dart
Lists
, Maps
e Futures
são os principais recursos da linguagem nos quais utilizamos os generics. É um bom hábito tirar vantagem do generics, visto que você traz mais segurança ao seu código através dessa camada a mais de tipagem, garantindo assim, que estamos trabalhando com os tipos de dados esperados.
Os generics em Lists
, por exemplo, podem ajudar a ter certeza de que cada elemento dentro de uma lista é de um determinado tipo, evitando assim que tenhamos erros por adicionar dados de tipos incorretos nessa lista.
Já as generics nas Futures
também são muito importantes, para que possamos ter uma maior confiabilidade nos dados que serão recebidos.
Generics com Lists e Maps
Você pode declarar variáveis em Lists
e Maps
sem generics como neste exemplo abaixo:
List minhaLista = [];
Map meuMap = {}
Dessa forma teremos uma lista que podem receber itens dynamic
e o map segue a mesma lógica, tendo a chave e valor dynamic.
Isso só deve ser feito quando você realmente precisa que suas Lists
e Maps
contenham múltiplos tipos diferentes. Caso você tenha certeza quais os tipos que essa lista e o map irão receber é interessante utilizar dos generics, justamente para que o compilador do Dart consiga te ajudar a trabalhar com esses dados.
Sendo assim, podemos utilizar os generics da seguinte forma:
List<String> minhaLista = ["Treinaweb", "Dart"];
Map<String, Object> meuMap = {"nome": "Treinaweb", "nota_curso": 5, "curso": "Dart"}
Generics em Dart utilizando nas Futures
Usamos operações assíncronas para que nosso sistema continue responsivo enquanto espera que uma operação que pode demorar algum tempo seja concluída.
Um exemplo é quando precisamos buscar dados em um banco de dados.
O Dart possui duas formas de trabalhar com código assíncrono, que é através das Futures
e Streams
.
É uma boa prática utilizar tipos ao lidar com código assíncrono, para que possamos saber quais os dados um código assíncrono pode retornar, isso ajuda no tratamento de erros uma vez saberemos qual o tipo dos dados que serão retornados. Não utilizar dessa boa pratica faz com que a nossa Future retorne um dado do tipo dynamic
e por conta disso acabamos perdendo a segurança de tipo facilitando em novos erros e adicionando uma maior dificuldade de dar manutenção.
Como utilizar generics em Futures
As Futures
no Dart são instâncias da classe Future
. Uma future representa o resultado de uma operação assíncrona, podendo ter dois estados, sendo eles, não concluídas ou concluídas.
Utilizando os generics em uma Future podemos saber o tipo do dado que será retornado.
Future<String> criarOrdem() async {
final ordem = await fetchOrdem();
return "Sua ordem é: $ordem";
}
Essa função retorna uma Future que tem como resultado uma String.
Curso Dart - Orientação a Objetos
Conhecer o cursoGenerics em métodos e funções
O Dart suporta generics em métodos e funções, isso é muito útil quando você quer reaproveitar código. Imagine que você quer executar uma função ou método e quer reaproveitar aquele código em diversas partes da aplicação.
Para fazer com que sua função ou método aceite valores genéricos basta colocar a declaração do generic entre o nome do método e os parênteses.
Um bom exemplo é quando queremos criar uma função que quer retornar o primeiro item de uma lista:
T primeiroValor<T>(List<T> lista){
return lista[0];
}
Classes que aceitam generics
Você também vai querer evitar criar classes separadas com o único propósito de lidar com diferentes tipos de dados. Um exemplo simples é quando você precisa criar uma classe que tem métodos futures e você não quer reescrever uma nova classe par cada tipo de dado.
class Rest<T>{
final RestClient _restClient;
Rest({requered RestClient restClient}):
_restClient = restClient;
Future<T> find<T>() async {
await return _restClient.get(url);
}
}
Essa classe irá me permitir que quando eu á instancie poderei informar com qual tipo quero trabalhar.
Para utilizar mais que uma generic basta separa-las por virgula
Conclusão
Neste artigo fizemos uma pequena introdução de como trabalhar com generics no Dart utilizando esse recurso em métodos, funções, classes, futures, maps e lists. saiba mais sobre o funcionamento do generics acessando a documentação do Dart
Caso queria aprender mais sobre Dart e sua infinidade de recursos saiba que aqui na Treinaweb nós temos o curso de Dart - Fundamentos que possui 02H21min de vídeo e um total de 18 exercicios. Conheça também nosso outros cursos de flutter e dart
Veja quais são os tópicos abordados durante o curso de Dart - Fundamentos:
- Como configurar seu ambiente de desenvolvimento
- O que são e como criar constantes e variaveis
- Como funcionam as estruturas de condições no Dart
- O que são e como criar estruturas de condições no Dart
- Como trabalhar com estrutura de repetição
- Como trabalhar com listas e mapas