Menu
Coddy logo textTech

Patterns & Matching (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 o pattern matching, uma maneira poderosa de desestruturar e inspecionar dados em uma única expressão. Patterns permitem extrair valores de objetos, verificar sua estrutura e vincular variáveis - tudo de uma vez.

Você já viu a desestruturação básica com records. Patterns estendem isso para funcionar com objetos, listas e mapas:

void main() {
  // Patterns de lista
  var numbers = [1, 2, 3];
  var [a, b, c] = numbers;
  print('$a, $b, $c');  // 1, 2, 3
  
  // Patterns de mapa
  var user = {'name': 'Alice', 'age': 30};
  var {'name': name, 'age': age} = user;
  print('$name is $age');  // Alice is 30
}

Padrões tornam-se especialmente poderosos em expressões switch. Você pode fazer a correspondência 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])); // Lista começando com 1
}

A cláusula when adiciona condições aos padrões, e ... corresponde aos elementos restantes em uma lista. O underscore _ atua como um curinga que corresponde a qualquer coisa. Combinados com classes seladas, os padrões permitem uma manipulação exaustiva e segura quanto ao tipo de estruturas de dados complexas.

challenge icon

Desafio

Fácil

Vamos construir um classificador de dados que utiliza correspondência de padrões (pattern matching) para analisar e categorizar diferentes tipos de entrada! Você criará um sistema que pode identificar e descrever várias estruturas de dados usando os poderosos recursos de pattern matching do Dart 3.

Você organizará seu código em dois arquivos:

  • classifier.dart: Crie uma função chamada classify que recebe um parâmetro Object e retorna uma String de descrição. Use uma expressão switch com pattern matching para lidar com estes casos:
    • Uma lista vazia [] deve retornar Empty list
    • Uma lista com exatamente um elemento inteiro deve retornar Single item: [value]
    • Uma lista com exatamente dois elementos deve retornar Pair: [first] and [second]
    • Uma lista começando com um inteiro seguido por mais elementos deve retornar List starting with [first], length: [total length] (use o padrão rest ...)
    • Um mapa contendo as chaves 'name' e 'age' deve retornar [name] is [age] years old (use a desestruturação de padrão de mapa)
    • Um número inteiro que seja negativo (use a cláusula when) deve retornar Negative: [value]
    • Um número inteiro que seja zero deve retornar Zero
    • Qualquer outro número inteiro deve retornar Positive: [value]
    • Qualquer outro valor deve retornar Unknown type
  • main.dart: Importe seu classificador e demonstre o pattern matching com várias entradas. Imprima o resultado da classificação de cada um destes valores:
    • Uma lista vazia []
    • Uma lista com um elemento: [42]
    • Uma lista com dois elementos: ['hello', 'world']
    • Uma lista mais longa: [1, 2, 3, 4, 5]
    • Um mapa: {'name': 'Alice', 'age': 25}
    • O número inteiro -10
    • O número inteiro 0
    • O número inteiro 99

Este desafio combina padrões de lista, padrões de mapa, a cláusula when para guardas e o padrão rest (...) - todos os principais recursos de pattern matching 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: 99

Folha de consulta

O Dart 3 introduziu o pattern matching para desestruturação e inspeção de dados em uma única expressão.

Padrões de Lista

Extraia valores de listas:

var numbers = [1, 2, 3];
var [a, b, c] = numbers;
print('$a, $b, $c');  // 1, 2, 3

Padrões de Mapa

Desestruture mapas por chave:

var user = {'name': 'Alice', 'age': 30};
var {'name': name, 'age': age} = user;
print('$name is $age');  // Alice is 30

Expressões Switch com Padrões

Corresponda por tipo, valor e estrutura:

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',
  };
}

Recursos de Padrões

  • Cláusula when: Adiciona condições aos padrões
  • ... (padrão rest): Corresponde aos elementos restantes em uma lista
  • _ (wildcard): Corresponde a qualquer coisa

Experimente você mesmo

import 'classifier.dart';

void main() {
  // TODO: Use a função classify para categorizar cada valor
  // e imprimir 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
}
quiz iconTeste seus conhecimentos

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