I. Ramificações básicas if / if-else
- A expressão dentro dos parênteses do
ifdeve ser sempre booleana; conversão implícita para tipo booleano não é permitida. - Vários blocos
else ifpodem ser encadeados, com um blocoelseopcional no final. - Chaves podem ser omitidas se houver apenas uma linha de código, mas recomenda-se usá-las todas as vezes para melhor legibilidade.
void main() {
bool isRaining = false;
bool isSnowing = true;
if (isRaining) {
print("Levar capa de chuva");
} else if (isSnowing) {
print("Vestir casaco grosso");
} else {
print("Dirigir conversível");
}
}Code language: Dart (dart)
Resultado da execução
D:\dartdemo\firstdart>dart run
Building package executable...
Built firstdart:firstdart.
Vestir casaco grossoCode language: CSS (css)
Também é possível usar o if isoladamente
void main() {
bool isRaining = false;
bool isSnowing = true;
if (isRaining) {
print("Levar capa de chuva");
}
}Code language: Dart (dart)
Ou apenas um if else
void main() {
bool isRaining = false;
bool isSnowing = true;
if (isRaining) {
print("Levar capa de chuva");
} else {
print("Dirigir conversível");
}
}Code language: Dart (dart)
II. Ramificação de casamento de padrão if-case (Dart 3.0+)
- Quando o padrão combinar, as variáveis são desestruturadas e vinculadas ao escopo atual.
- Se o casamento falhar, o código pula para o else. Você pode adicionar um guard
whenpara validações booleanas extras. - Destinado ao casamento de um valor com um único padrão; utilize switch quando precisar lidar com vários padrões.
void main() {
final pair = [100, 220];
// Casa com uma lista contendo dois números inteiros
if (pair case [int x, int y]) {
print("Coordenada: $x,$y");
} else {
throw FormatException("Coordenada inválida");
}
}Code language: Dart (dart)
Resultado da execução
D:\dartdemo\firstdart>dart run
Building package executable...
Built firstdart:firstdart.
Coordenada: 10,20Code language: CSS (css)
2: if-case combinado com guard when
void main() {
final data = [8, 9];
if (data case [int a, int b] when a > 5 && b > 5) {
print("Os dois números são maiores que 5");
} else {
print("Os números não atendem à condição");
}
}Code language: Dart (dart)
Resultado da execução
D:\dartdemo\firstdart>dart run
Building package executable...
Built firstdart:firstdart.
Os dois números são maiores que 5Code language: CSS (css)
III. Comando switch
Switch tradicional no formato de comando, sem valor de retorno
- Cases aceitam todos os tipos de padrões: strings, constantes, OU lógico, padrões relacionais
- Cases com conteúdo saem automaticamente com break, não é necessário escrever break manualmente; cases vazios causam fallthrough implícito.
- Duas formas de forçar fallthrough manual:
continue rótuloou encadear casos vazios - O bloco
defaultexecuta quando nenhum case combinar; compatível com guardswhen
1: Casamento básico de string
void main() {
String command = "OPEN";
switch (command) {
case "CLOSED":
print("Executar lógica de fechamento");
case "PENDING":
print("Executar lógica de espera");
case "OPEN":
print("Executar lógica de abertura");
default:
print("Comando desconhecido");
}
}
Code language: Dart (dart)
Resultado da execução
D:\dartdemo\firstdart>dart run
Building package executable...
Built firstdart:firstdart.
Executar lógica de aberturaCode language: CSS (css)
2: Fallthrough com case vazio + salto via continue rótulo
String command = "OPEN";
switch (command) {
case "OPEN":
print("Operação de abertura"); // ① Combina com OPEN e executa a impressão
continue newCase; // ② Salta diretamente para o rótulo newCase, não retorna
case "DENIED":
case "CLOSED":
print("Operação de fechamento");
newCase: // ③ Destino do salto
case "PENDING":
print("Lógica unificada para processos pendentes"); // ④ Executado sem verificar command == "PENDING"
}Code language: Dart (dart)
Resultado da execução
D:\dartdemo\firstdart>dart run
Building package executable...
Built firstdart:firstdart.
Operação de abertura
Lógica unificada para processos pendentesCode language: CSS (css)
Neste exemplo,
continue newCase;salta para o rótulo newCase, mas o case seguinte “PENDING” não combina, por que o códigoprint("Lógica unificada para processos pendentes");mesmo assim roda?Essa é uma dúvida recorrente dos leitores
continue rótulo; não reavalia o valor testado, salta direto para o início do bloco case marcado pelo rótulo, ignora todas as validações de condição e executa o código do bloco imediatamente.
3: switch com guard when
void main() {
int score = 88;
switch (score) {
case int s when s >= 90:
print("Excelente");
case int s when s >= 60:
print("Aprovado");
default:
print("Reprovado");
}
}
Code language: Dart (dart)
Saída: Aprovado
Primeiro valida o tipo: o valor precisa ser inteiro. Se for, atribui à variável s. Depois o guard when faz uma segunda validação; o código do case só roda se s atender à condição do when. As duas declarações int s têm escopos independentes e não interferem uma na outra.
Cada case int s é uma vinculação de padrão independente, cujo escopo é restrito apenas ao seu próprio bloco case.
Você pode usar nomes de variáveis diferentes sem alterar o funcionamento do código.
switch (score) {
case int a when a >= 90:
print("Excelente");
case int b when b >= 60:
print("Aprovado");
default:
print("Reprovado");
}Code language: Dart (dart)
IV. Expressão switch
Sintaxe liberada a partir do Dart 3.0, possui valor de retorno e é amplamente utilizada para atribuição de variáveis
Diferenças em relação ao comando switch
- Não existe a palavra-chave
case; o símbolo=>separa o padrão e a expressão de retorno - Cada ramificação deve retornar uma expressão, as ramificações são separadas por vírgulas
- Não há fallthrough implícito, cada ramificação é independente. Quando nenhum padrão combinar, use o sublinhado
_ao invés de default - Pode ser usado diretamente em atribuições, chamadas print, return e qualquer contexto de expressão
1: Casamento básico de operadores de caractere (padrão OU lógico)
void main() {
const slash = 47, star = 42, comma = 44;
int charCode = 42;
final token = switch (charCode) {
slash || star => "Operador",
comma => "Pontuação",
_ => "Caractere inválido"
};
print(token);
}
Code language: Dart (dart)
Resultado da execução
Operador
Esse exemplo define constantes com os códigos ASCII de três símbolos e classifica o caractere da variável charCode como operador, pontuação ou símbolo inválido.
2: Expressão switch com guard when
void main() {
int age = 22;
String level = switch (age) {
int a when a < 18 => "Menor de idade",
int a when a < 30 => "Jovem adulto",
_ => "Adulto"
};
print(level);
}Code language: Dart (dart)
Resultado da execução
Jovem adulto
3: Uso direto da expressão switch no retorno de função
void main() {
print(getDesc(3));
}
String getDesc(int num) => switch (num) {
1 => "Um",
2 => "Dois",
_ => "Outro número"
};
Code language: Dart (dart)
Resultado da execução
Outro número
Observação: Aqui o switch é uma expressão e getDesc é uma função de seta. Funções de seta são uma sintaxe exclusiva do Dart que não existe em outras linguagens da família C.
V. Verificação de exaustividade (Exhaustiveness Checking)
Erro em tempo de compilação se faltarem cases para valores de entrada possíveis; o compilador obriga a completar todos os casos. Classes sealed e enums suportam verificação exaustiva nativamente sem necessidade de _ ou default.
1: Erro de falta de exaustividade em booleano anulável (comente/descomente para visualizar o erro)
void main() {
bool? nullableBool = null;
// Descomentar o código abaixo causa erro de compilação: falta case para null e não há fallback com _/default
/*
switch (nullableBool) {
case true:
print("Verdadeiro");
case false:
print("Falso");
}
*/
// Correção: adicionar case null ou fallback com _
switch (nullableBool) {
case true:
print("Verdadeiro");
case false:
print("Falso");
case null:
print("Valor nulo");
}
}Code language: PHP (php)
Resultado da execução
Valor nulo
2: Classe sealed (selada)
Tipo de dado algébrico que força o casamento completo de padrões
import 'dart:math' as math;
// Classe sealed: subclasses só podem ser definidas neste arquivo
sealed class Shape {}
// Subclasse Quadrado: comprimento do lado
class Square implements Shape {
final double length;
Square(this.length);
}
//Subclasse Círculo: raio
class Circle implements Shape {
final double radius;
Circle(this.radius);
}
// Função de seta que calcula a área via casamento switch no objeto de subclasse recebido
double calculateArea(Shape shape) => switch (shape) {
Square(length: var l) => l * l,
Circle(radius: var r) => math.pi * r * r
// Adicionar nova subclasse de Shape gera erro de compilação por falta de case
};
void main() {
final Shape circle = Circle(5);
print(calculateArea(circle));
final Shape square = Square(4);
print(calculateArea(square));
}
Code language: Dart (dart)
Resultado da execução
78.53981633974483
16.0Code language: CSS (css)
3: Casamento exaustivo com enum
Não é necessário o sublinhado de fallback _
void main() {
final Animal animal = Animal.cat;
String name = switch (animal) {
Animal.dog => "Cachorro",
Animal.cat => "Gato"
};
print(name);
}
enum Animal { dog, cat }
Code language: Dart (dart)
Saída: Gato
Enums possuem um conjunto finito e fixo de valores, então não é preciso criar ramificação de fallback.
VI. Guards when
Suportados em if-case, comandos switch e expressões switch
Função do when: executar validação booleana extra após o casamento bem-sucedido do padrão. Se o guard retornar false, segue para a próxima ramificação sem sair do switch.
1. if-case + when
void main() {
List<int> arr = [10, 20];
if (arr case [int x, int y] when x + y > 20) {
print("A soma dos dois números é maior que 20");
}
}Code language: Dart (dart)
A soma dos dois números é maior que 20
Primeiro verifica se é uma lista com dois inteiros; se o padrão combinar, o when checa se a soma ultrapassa 20.
2. Comando switch + when
void main() {
int num = 15;
switch(num) {
case int n when n % 2 == 0:
print("Número par");
case int n when n % 2 != 0:
print("Número ímpar");
}
}
Code language: PHP (php)
Saída: Número ímpar
Primeiro confirma que o tipo é inteiro, depois valida a condição dentro do when.
3. Expressão switch + when
void main() {
int num = 15;
String res = switch(num) {
int n when n % 2 == 0 => "Número par",
_ => "Número ímpar"
};
print(res);
}
Code language: PHP (php)