Mobile App Development · Dart/Flutter

22 · Nullability Safety — Desafios

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

desafio_01_perfil_usuario.dart

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

desafio_02_resposta_api.dart

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