DEV Community

Toshi Ossada for flutterbrasil

Posted on

Uma nova forma de utilizar os Switch Case no Dart 3

O Dart 3 nos trouxe muitas novidades incríveis, e já abordei de algumas por aqui, um recurso muito legal foi o que denominamos de Switch Expressions.

A forma tradicional do Dart é utilizarmos o switch statement que é uma forma imperativa e procedural que estamFos acostumados.

enum MesEnum {
janeiro('Janeiro'),
fevereiro('Fevereiro'),
marco('Março'),
abril('Abril'),
maio('Maio'),
junho('Junho'),
julho('Julho'),
agosto('Agosto'),
setembro('Setembro'),
outubro('Outubro'),
novembro('Novembro'),
dezembro('Dezembro');
final String description;
const MesEnum(this.description);
}
String pegarMes(int mes) {
late String result;
switch (mes) {
case 1:
result = MesEnum.janeiro.description;
break;
case 2:
result = MesEnum.fevereiro.description;
break;
case 3:
result = MesEnum.marco.description;
break;
case 4:
result = MesEnum.abril.description;
break;
case 5:
result = MesEnum.maio.description;
break;
case 6:
result = MesEnum.junho.description;
break;
case 7:
result = MesEnum.julho.description;
break;
case 8:
result = MesEnum.agosto.description;
break;
case 9:
result = MesEnum.setembro.description;
break;
case 10:
result = MesEnum.outubro.description;
break;
case 11:
result = MesEnum.novembro.description;
break;
case 12:
result = MesEnum.dezembro.description;
break;
default:
result = 'Mês inválido';
}
return result;
}
void main() {
int mes = 1;
String result = pegarMes(mes);
print(result);
}
view raw playground.dart hosted with ❤ by GitHub

Note que, da forma antiga, com a Switch Statement não temos a capacidade de retornar diretamente o valor à variável, com a nova maneira utilizando Switch Expression traz uma importante mudança de introduzir aspectos da programação funcional para o Dart trazendo a linguagem mais flexibilidade e poder.

Um dos principais avanços das Switch Expressions no Dart 3 é a adoção de uma sintaxe similar às arrow arrow functions para mapear os cases diretamente ao valor de saída. Isso melhora a legibilidade do código e o torna menos propenso a erros.

enum MesEnum {
janeiro('Janeiro'),
fevereiro('Fevereiro'),
marco('Março'),
abril('Abril'),
maio('Maio'),
junho('Junho'),
julho('Julho'),
agosto('Agosto'),
setembro('Setembro'),
outubro('Outubro'),
novembro('Novembro'),
dezembro('Dezembro');
final String description;
const MesEnum(this.description);
}
String pegarMes(int mes) {
final result = switch (mes) {
1 => MesEnum.janeiro.description,
2 => MesEnum.fevereiro.description,
3 => MesEnum.marco.description,
4 => MesEnum.abril.description,
5 => MesEnum.maio.description,
6 => MesEnum.junho.description,
7 => MesEnum.julho.description,
8 => MesEnum.agosto.description,
9 => MesEnum.setembro.description,
10 => MesEnum.outubro.description,
11 => MesEnum.novembro.description,
12 => MesEnum.dezembro.description,
_ => 'Mês inválido', //Valor padrão, substitui o default
};
return result;
}
void main() {
int mes = 1;
String result = pegarMes(mes);
print(result);
}
view raw playground.dart hosted with ❤ by GitHub

Note que o default foi substituído apenas pelo _ (underline). Podemos melhorar ainda mais nosso código da seguinte forma:

enum MesEnum {
janeiro('Janeiro'),
fevereiro('Fevereiro'),
marco('Março'),
abril('Abril'),
maio('Maio'),
junho('Junho'),
julho('Julho'),
agosto('Agosto'),
setembro('Setembro'),
outubro('Outubro'),
novembro('Novembro'),
dezembro('Dezembro');
final String description;
const MesEnum(this.description);
}
String pegarMes(int mes) => switch (mes) {
1 => MesEnum.janeiro.description,
2 => MesEnum.fevereiro.description,
3 => MesEnum.marco.description,
4 => MesEnum.abril.description,
5 => MesEnum.maio.description,
6 => MesEnum.junho.description,
7 => MesEnum.julho.description,
8 => MesEnum.agosto.description,
9 => MesEnum.setembro.description,
10 => MesEnum.outubro.description,
11 => MesEnum.novembro.description,
12 => MesEnum.dezembro.description,
_ => 'Mês inválido', //Valor padrão, substitui o default
};
void main() {
int mes = 1;
String result = pegarMes(mes);
print(result);
}
view raw playground.dart hosted with ❤ by GitHub

Pattern Matching

Outro recurso bastante interessante é o Pattern Matching, com ele você pode desestruturar um objeto complexo ao mesmo tempo em que está validando uma condição e utilizar esses valores dentro da condição, no Dart 3 você pode utilizar o Pattern Matching dentro de suas condições switchs.

Veja no exemplo a seguir:

sealed class Funcionario {
final String nome;
Funcionario({
required this.nome,
});
double calcularPagamento();
}
class Estagiario extends Funcionario {
final double bolsaAuxilio;
Estagiario({
required super.nome,
required this.bolsaAuxilio,
});
@override
double calcularPagamento() => bolsaAuxilio;
}
class CLT extends Funcionario {
final double salario;
CLT({
required super.nome,
required this.salario,
});
double _calcularIRPF() => salario * 0.15;
@override
double calcularPagamento() => salario - _calcularIRPF();
}
void main() {
Funcionario empregado = Estagiario(nome: 'Toshi', bolsaAuxilio: 1000);
final relatorio = switch (empregado) {
(Estagiario estag) =>
'${estag.nome} Pagamento bruto: R\$${estag.bolsaAuxilio}, Pagamento Liquido: R\$${estag.calcularPagamento()}, Cargo: Estagiário',
(CLT clt) =>
'${clt.nome} Pagamento bruto: R\$${clt.salario}, Pagamento Liquido: R\$${clt.calcularPagamento()}, Cargo: CLT',
};
print(relatorio);
}
view raw playground.dart hosted with ❤ by GitHub

Guard Clauses

Como mostrei em artigos no Dart 3 temos os records, agora conseguimos usar os pattern matching em conjunto com os records, essa poderosa junção permite com que possamos desestruturar dados e executar uma condição nos dados desestruturados, utilizando a palavra reservada when para especificar a condição.

void main() {
final usuario = 'toshiossada';
final senha = '123456';
final msg = switch ((usuario, senha)) {
(String user, String password)
when user == 'toshiossada' && password == '123456' =>
'LOGIN REALIZADO COM SUCESSO',
(_, _) => 'Usuario ou senha inválidos'
};
print(msg);
}
view raw playground.dart hosted with ❤ by GitHub

Sendo que os valores também podem ser providos de uma função.

(String, String) realizarLogin() {
final usuario = 'toshiossada';
final senha = '1234564';
return (usuario, senha);
}
void main() {
final login = realizarLogin();
final msg = switch (login) {
(String user, String password)
when user == 'toshiossada' && password == '123456' =>
'LOGIN REALIZADO COM SUCESSO',
_ => 'Usuario ou senha inválidos'
};
print(msg);
}
view raw playground.dart hosted with ❤ by GitHub

Com toda certeza essas novas features deixam o Dart cada vez mais com uma cara de programação funcional, o Dart vem trazendo o que há de melhor da programação funcional e imperativa deixando o código mais legível, eficiente e testável

Image description

Entre em nosso discord para interagir com a comunidade: flutterbrasil.com.br

AWS Security LIVE!

Join us for AWS Security LIVE!

Discover the future of cloud security. Tune in live for trends, tips, and solutions from AWS and AWS Partners.

Learn More

Top comments (0)

Sentry blog image

The Visual Studio App Center’s retiring

But sadly….you’re not. See how to make the switch to Sentry for all your crash reporting needs.

Read more

AWS Security LIVE!

Hosted by security experts, AWS Security LIVE! showcases AWS Partners tackling real-world security challenges. Join live and get your security questions answered.

Tune in to the full event

DEV is partnering to bring live events to the community. Join us or dismiss this billboard if you're not interested. ❤️