Menu
Coddy logo textTech

Os operadores ? e !

Parte da seção Programação Orientada a Objetos do Journey de Dart da Coddy. Lição 25 de 110.

Ao trabalhar com tipos anuláveis, o Dart fornece dois operadores essenciais para acessar valores com segurança. O operador de acesso condicional (null-aware) ?. e o operador de asserção nula (null assertion) ! oferecem controle sobre como você lida com valores potencialmente nulos.

O operador ?. acessa com segurança propriedades ou métodos em um valor anulável. Se o valor for null, toda a expressão retornará null em vez de causar um erro:

String? name = 'Alice';
print(name?.length);  // 5

name = null;
print(name?.length);  // null (sem erro!)

O operador ! informa ao Dart: "Tenho certeza de que este valor não é nulo." Ele converte um tipo anulável em não anulável, mas gera um erro se o valor for realmente nulo:

String? maybeName = 'Bob';
String definite = maybeName!;  // OK - afirmamos que não é nulo
print(definite.length);  // 3

String? empty = null;
// String crash = empty!;  // Erro de tempo de execução! O valor era nulo

Use ?. quando você quiser lidar graciosamente com valores nulos. Use ! apenas quando tiver certeza absoluta de que um valor existe - talvez após verificá-lo com uma instrução if ou quando souber que a lógica garante um valor. O uso excessivo de ! anula o propósito da segurança de nulos (null safety) e pode levar a falhas em tempo de execução.

challenge icon

Desafio

Fácil

Vamos criar um sistema de inventário de produtos que demonstra como trabalhar com segurança com valores anuláveis usando os operadores ?. e !.

Você criará dois arquivos para organizar seu código:

  • product.dart: Defina uma classe Product que represente um item do inventário. Alguns produtos têm informações completas, enquanto outros ainda estão sendo catalogados. Sua classe deve ter:
    • Uma String name não anulável — todo produto deve ter um nome
    • Um double price não anulável — todo produto deve ter um preço
    • Uma String? description anulável — alguns produtos ainda não têm descrição
    • Uma String? category anulável — alguns produtos ainda não foram categorizados
    • Um construtor que aceite name e price como parâmetros obrigatórios
    • Um método getDescriptionLength() que retorne o tamanho da descrição usando ?., ou null se não houver descrição
    • Um método getCategoryUppercase() que retorne a categoria em letras maiúsculas usando ! — esse método pressupõe que a categoria foi definida
    • Um método displayProduct() que imprima as informações do produto, exibindo No description quando a descrição for nula e Uncategorized quando a categoria for nula
  • main.dart: Importe sua classe de produto e demonstre ambos os operadores:
    • Crie um produto chamado 'Laptop' com preço 999.99, depois defina sua descrição como 'High-performance computing device' e sua categoria como 'Electronics'
    • Crie um produto chamado 'Mystery Item' com preço 49.99 (deixe a descrição e a categoria como null)
    • Para o Laptop: chame displayProduct(), imprima Description length: [length] usando getDescriptionLength() e imprima Category: [uppercase] usando getCategoryUppercase()
    • Para o Mystery Item: chame displayProduct() e imprima Description length: [length] usando getDescriptionLength() (isso exibirá null)

O método displayProduct() deve imprimir neste formato:

Product: [name] - $[price]
Description: [description or "No description"]
Category: [category or "Uncategorized"]

Saída esperada:

Product: Laptop - $999.99
Description: High-performance computing device
Category: Electronics
Description length: 32
Category: ELECTRONICS
Product: Mystery Item - $49.99
Description: No description
Category: Uncategorized
Description length: null

Experimente você mesmo

import 'product.dart';

void main() {
  // TODO: Crie um produto chamado 'Laptop' com o preço 999.99
  // Depois, defina sua descrição como 'High-performance computing device'
  // E defina sua categoria como 'Electronics'
  
  // TODO: Crie um produto chamado 'Mystery Item' com o preço 49.99
  // Deixe a descrição e a categoria como null
  
  // TODO: Para o Laptop:
  // - Chame displayProduct()
  // - Imprima "Description length: [length]" usando getDescriptionLength()
  // - Imprima "Category: [uppercase]" usando getCategoryUppercase()
  
  // TODO: Para o Mystery Item:
  // - Chame displayProduct()
  // - Imprima "Description length: [length]" usando getDescriptionLength()
}
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

Pratique por conta própria: Compilador de Dart online