Menu
Coddy logo textTech

Los operadores ? y !

Parte de la sección Programación Orientada a Objetos del Journey de Dart de Coddy — lección 25 de 110.

Al trabajar con tipos que admiten valores nulos, Dart proporciona dos operadores esenciales para acceder a los valores de forma segura. El operador de acceso null-aware ?. y el operador de aserción nula ! te brindan control sobre cómo manejas los valores potencialmente nulos.

El operador ?. accede de forma segura a propiedades o métodos en un valor que admite nulos. Si el valor es null, toda la expresión devuelve null en lugar de fallar:

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

name = null;
print(name?.length);  // null (¡sin errores!)

El operador ! le dice a Dart "estoy seguro de que este valor no es nulo". Convierte un tipo nullable a non-nullable, pero lanza un error si el valor es realmente nulo:

String? maybeName = 'Bob';
String definite = maybeName!;  // OK - afirmamos que no es nulo
print(definite.length);  // 3

String? empty = null;
// String crash = empty!;  // ¡Error en tiempo de ejecución! El valor era nulo

Usa ?. cuando quieras manejar valores nulos de forma elegante. Usa ! solo cuando estés absolutamente seguro de que existe un valor, quizás después de comprobarlo con una sentencia if o cuando sepas que la lógica garantiza un valor. El uso excesivo de ! anula el propósito de la seguridad contra nulos y puede provocar fallos en tiempo de ejecución.

challenge icon

Desafío

Fácil

Vamos a construir un sistema de inventario de productos que demuestre cómo trabajar de forma segura con valores nulos utilizando los operadores ?. y !.

Crearás dos archivos para organizar tu código:

  • product.dart: Define una clase Product que represente un artículo en el inventario. Algunos productos tienen información completa, mientras que otros aún se están catalogando. Tu clase debe tener:
    • Un String name no nulo: cada producto debe tener un nombre
    • Un double price no nulo: cada producto debe tener un precio
    • Un String? description nulo: algunos productos aún no tienen descripción
    • Un String? category nulo: algunos productos no han sido categorizados
    • Un constructor que tome name y price como parámetros requeridos
    • Un método getDescriptionLength() que devuelva la longitud de la descripción usando ?., o null si no hay descripción
    • Un método getCategoryUppercase() que devuelva la categoría en mayúsculas usando !; este método asume que la categoría ha sido establecida
    • Un método displayProduct() que imprima la información del producto, mostrando "No description" cuando la descripción sea nula y "Uncategorized" cuando la categoría sea nula
  • main.dart: Importa tu clase de producto y demuestra ambos operadores:
    • Crea un producto llamado 'Laptop' con un precio de 999.99, luego establece su descripción como 'High-performance computing device' y su categoría como 'Electronics'
    • Crea un producto llamado 'Mystery Item' con un precio de 49.99 (deja la descripción y la categoría como nulas)
    • Para la Laptop: llama a displayProduct(), imprime 'Description length: [length]' usando getDescriptionLength(), e imprime 'Category: [uppercase]' usando getCategoryUppercase()
    • Para el Mystery Item: llama a displayProduct() e imprime 'Description length: [length]' usando getDescriptionLength() (esto mostrará null)

El método displayProduct() debe imprimir en este formato:

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

Salida 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

Pruébalo tú mismo

import 'product.dart';

void main() {
  // TODO: Crea un producto llamado 'Laptop' con el precio 999.99
  // Luego establece su descripción como 'High-performance computing device'
  // Y establece su categoría como 'Electronics'
  
  // TODO: Crea un producto llamado 'Mystery Item' con el precio 49.99
  // Deja la descripción y la categoría como null
  
  // TODO: Para la Laptop:
  // - Llama a displayProduct()
  // - Imprime "Description length: [length]" usando getDescriptionLength()
  // - Imprime "Category: [uppercase]" usando getCategoryUppercase()
  
  // TODO: Para el Mystery Item:
  // - Llama a displayProduct()
  // - Imprime "Description length: [length]" usando getDescriptionLength()
}
quiz iconPonte a prueba

Esta lección incluye un breve cuestionario. Empieza la lección para responderlo y registrar tu progreso.

Todas las lecciones de Programación Orientada a Objetos