Padrões e Correspondência (3.0)
Parte da seção Programação Orientada a Objetos do Journey de Dart da Coddy. Lição 87 de 110.
O Dart 3 introduziu a correspondência de padrões, uma forma poderosa de desestruturar e inspecionar dados em uma única expressão. Os padrões permitem extrair valores de objetos, verificar sua estrutura e associar variáveis — tudo de uma só vez.
Você já viu a desestruturação básica com registros. Os padrões expandem isso para funcionar com objetos, listas e mapas:
void main() {
// Padrões de lista
var numbers = [1, 2, 3];
var [a, b, c] = numbers;
print('$a, $b, $c'); // 1, 2, 3
// Padrões de mapa
var user = {'name': 'Alice', 'age': 30};
var {'name': name, 'age': age} = user;
print('$name is $age'); // Alice is 30
}Os padrões se tornam especialmente poderosos em expressões switch. Você pode fazer correspondências de tipo, valor e estrutura simultaneamente:
String describe(Object obj) {
return switch (obj) {
int n when n < 0 => 'Negative number',
int n => 'Positive number: $n',
String s => 'String of length ${s.length}',
[int first, ...] => 'List starting with $first',
_ => 'Something else',
};
}
void main() {
print(describe(-5)); // Número negativo
print(describe(42)); // Número positivo: 42
print(describe([1, 2, 3])); // List starting with 1
}A cláusula when adiciona condições aos padrões, e ... corresponde aos elementos restantes em uma lista. O sublinhado _ funciona como um curinga que corresponde a qualquer coisa. Combinados com classes seladas, os padrões permitem o tratamento exaustivo e com segurança de tipos de estruturas de dados complexas.
Desafio
FácilVamos criar um classificador de data que usa correspondência de padrões para analisar e categorizar diferentes tipos de input! Você criará um sistema capaz de identificar e descrever várias estruturas de data usando os poderosos recursos de correspondência de padrões do Dart 3.
Você organizará seu código em dois arquivos:
classifier.dart: crie uma function chamadaclassifyque recebe um parâmetroObjecte retorna uma descriçãoString. Use uma expressão switch com correspondência de padrões para lidar com estes casos:- Um list vazio
[]deve retornarEmpty list - Um list com exatamente um elemento integer deve retornar
Single item: [value] - Um list com exatamente dois elements deve retornar
Pair: [first] and [second] - Um list começando com um integer seguido por mais elements deve retornar
List starting with [first], length: [total length](use o padrão rest...) - Um map contendo ambas as chaves
'name'e'age'deve retornar[name] is [age] years old(use a desestruturação de padrões de map) - Um integer negativo (use a cláusula
when) deve retornarNegative: [value] - Um integer que seja zero deve retornar
Zero - Qualquer outro integer deve retornar
Positive: [value] - Qualquer outro valor deve retornar
Unknown type
- Um list vazio
main.dart: importe seu classifier e demonstre a correspondência de padrões com vários inputs. Imprima o resultado de classificar cada um destes valores:- Um list vazio
[] - Um list com um elemento:
[42] - Um list com dois elements:
['hello', 'world'] - Um list mais longo:
[1, 2, 3, 4, 5] - Um map:
{'name': 'Alice', 'age': 25} - O integer
-10 - O integer
0 - O integer
99
- Um list vazio
Este desafio combina padrões de list, padrões de map, a cláusula when para guards e o padrão rest (...) — todos os principais recursos de correspondência de padrões da lição!
Saída esperada:
Empty list
Single item: 42
Pair: hello and world
List starting with 1, length: 5
Alice is 25 years old
Negative: -10
Zero
Positive: 99Experimente você mesmo
import 'classifier.dart';
void main() {
// TODO: Use a função classify para categorizar cada valor
// e imprima os resultados
// Teste com uma lista vazia
print(classify([]));
// TODO: Teste com uma lista contendo um elemento: [42]
// TODO: Teste com uma lista contendo dois elementos: ['hello', 'world']
// TODO: Teste com uma lista mais longa: [1, 2, 3, 4, 5]
// TODO: Teste com um map: {'name': 'Alice', 'age': 25}
// TODO: Teste com o inteiro -10
// TODO: Teste com o inteiro 0
// TODO: Teste com o inteiro 99
}
Esta lição inclui um quiz rápido. Comece a lição para respondê-lo e acompanhar seu progresso.
Todas as lições de Programação Orientada a Objetos
1Fundamentos de OOP
Arquivos externosBibliotecas e importsIntrodução à OOPClasses vs. objetosA palavra-chave thisMétodosVariáveis de instânciaNoções básicas de construtoresRevisão - Calculadora simples4Segurança contra nulos
Introdução à segurança contra nulosAnulável vs. não anulávelOs operadores ? e !Palavra-chave Late e segurança contra nulosOperadores conscientes de nulosSegurança contra nulos em classesRecapitulação — Sistema de perfil de usuário7Classes Abstratas e Interfaces
Classes AbstratasMétodos AbstratosInterfaces em DartInterfaces ImplícitasImplementação vs. ExtensãoMúltiplas InterfacesRecapitulação - Calculadora de Formas10Coleções e Genéricos
Visão geral de List, Set e MapColeções com segurança de tiposClasses genéricasMétodos genéricosRestrições genéricasIterable e IteratorRecapitulação - Armazenamento genérico13Conceitos Avançados de OOP
Composição vs. HerançaMétodos de ExtensãoClasses ChamáveisClasses Seladas (Dart 3)Registros (Dart 3)Padrões e Correspondência (3.0)Enums com Métodos16Projeto: Gerenciamento de Biblioteca
Visão Geral do ProjetoClasses de Livros e Usuários2Construtores em Dart
Construtor padrãoConstrutores nomeadosListas de inicializaçãoConstrutores constantesConstrutores factoryConstrutores de redirecionamentoRevisão - Construtor de formas5Encapsulamento
Membros Públicos vs. PrivadosConvenção do Prefixo _Privacidade no Nível da BibliotecaAprofundamento em Getters e SettersOcultação de InformaçõesRecapitulação - Registros de Alunos8Mixins
Introdução a MixinsCriando MixinsUsando vários MixinsPalavra-chave on em MixinsMixin vs HerançaMixin vs InterfaceRecapitulação - Sistema de Animais11Métodos Especiais
Sobrescrita de toString()Sobrescrita de hashCode e ==Interface ComparableMétodo call()Sobrescrita de noSuchMethodRecapitulação - Coleção Personalizada14Padrões de Projeto – Parte 1
Introdução aos Padrões de ProjetoPadrão SingletonPadrão FactoryPadrão ObserverPadrão Strategy3Propriedades de Classe
Membros de Instância vs. EstáticosCampos Final e ConstVariáveis LateMétodos e Campos EstáticosGetters e SettersRecapitulação - Gerenciador de Contas Bancárias6Herança
Herança BásicaA Palavra-chave superSobrescrita de MétodosA Anotação @overrideA Palavra-chave final para ClassesConstrutores e HerançaRecapitulação - Hierarquia de Funcionários9Polimorfismo
Fundamentos do polimorfismoPolimorfismo por meio de interfacesVerificação de tipos em tempo de execuçãoOs operadores is e asPalavra-chave covarianteRecapitulação — Processador de pagamentos12OOP Assíncrona
Futures e async/awaitNoções básicas de StreamsControladores de StreamConstrutores assíncronosAsync em métodos de classeRecapitulação — Buscador de dados15Padrões de Projeto — Parte 2
Padrão CommandPadrão AdapterPadrão DecoratorPadrão Template MethodPadrão StatePadrão CompositePadrão RepositoryPratique por conta própria: Compilador de Dart online