Mobile App Development · Dart/Flutter
Dois desafios que aplicam null safety em cenários reais: um perfil de usuário com campos opcionais e uma resposta de API simulada com dados nullable.
Desafio 1
Modela um perfil de usuário com nome obrigatório e os campos opcionais apelido, telefone e cidade como String?. O construtor usa required apenas para o campo obrigatório, e o método exibirResumo usa ?? para mostrar um valor padrão em cada campo não informado.
// Desafio: modelar um perfil de usuário com atributos opcionais usando null safety.
// Demonstra o uso de String?, ?? e parâmetros nomeados opcionais em classes.
class PerfilUsuario {
// Atributo obrigatório: o nome sempre deve ser informado.
final String nome;
// Atributos opcionais: podem ser null se não forem fornecidos.
final String? apelido;
final String? telefone;
final String? cidade;
// Construtor nomeado com 'nome' obrigatório e demais campos opcionais.
// Campos nullable não precisam de 'required' — são null se não informados.
PerfilUsuario({required this.nome, this.apelido, this.telefone, this.cidade});
// Exibe o perfil com valores alternativos para campos não informados.
void exibirResumo() {
print('Nome: $nome');
// ?? substitui null por texto padrão caso o campo não tenha sido preenchido.
print('Apelido: ${apelido ?? 'Sem apelido'}');
print('Telefone: ${telefone ?? 'Nao informado'}');
print('Cidade: ${cidade ?? 'Nao informada'}');
}
}
void main() {
// Cria um perfil com apenas nome e cidade — apelido e telefone ficam null.
PerfilUsuario perfil = PerfilUsuario(nome: 'Ana', cidade: 'Recife');
// O método exibirResumo usa ?? para tratar os campos null automaticamente.
perfil.exibirResumo();
}
Saída esperada
Nome: Ana Apelido: Sem apelido Telefone: Nao informado Cidade: Recife
Como executar
dart run 22-Nullability_Safety/03_Desafios/codigo_fonte/desafio_01_perfil_usuario.dart
Desafio 2
Simula uma resposta de API como Map<String, dynamic>, onde o campo email vem como null. Usa ?? para fornecer textos alternativos e uma checagem if (idade != null) — com promoção de tipo — para operar sobre idade sem recorrer ao operador !.
// Desafio: processar uma resposta de API com campos nullable.
// Demonstra como lidar com dados que podem ou não estar presentes em uma resposta.
void main() {
// Simula uma resposta de API como um Map com valores mistos.
// O campo 'email' é null — como se a API não tivesse retornado esse dado.
Map<String, dynamic> resposta = {'nome': 'Ana', 'email': null, 'idade': 24};
// ?? fornece valor alternativo quando o campo for null.
// resposta['nome'] é 'Ana' (não null), então usa o valor real.
String nome = resposta['nome'] ?? 'Nome nao informado';
// resposta['email'] é null, então usa o texto alternativo.
String email = resposta['email'] ?? 'E-mail nao informado';
// int? permite armazenar o valor int ou null do Map.
int? idade = resposta['idade'];
print('=== Resposta da API ===');
print('Nome: $nome');
print('E-mail: $email');
// Verifica se idade foi informada antes de operar sobre ela.
// Type promotion: dentro do if, 'idade' é tratado como int (não int?).
if (idade != null) {
// Calcula a idade no próximo ano — só possível pois verificamos que não é null.
print('Idade no proximo ano: ${idade + 1}');
} else {
print('Idade nao informada');
}
}
Saída esperada
=== Resposta da API === Nome: Ana E-mail: E-mail nao informado Idade no proximo ano: 25
Como executar
dart run 22-Nullability_Safety/03_Desafios/codigo_fonte/desafio_02_resposta_api.dart