Operadores Null-aware
Parte de la sección Programación Orientada a Objetos del Journey de Dart de Coddy — lección 27 de 110.
Más allá de ?. y !, Dart proporciona operadores adicionales que hacen que trabajar con valores que pueden ser nulos sea más conciso. Estos operadores null-aware te ayudan a escribir código más limpio al tratar con posibles valores nulos.
El operador de coalescencia nula ?? devuelve el valor de la izquierda si no es nulo; de lo contrario, devuelve el valor de la derecha:
String? nickname;
String displayName = nickname ?? 'Guest';
print(displayName); // Guest
nickname = 'Alex';
displayName = nickname ?? 'Guest';
print(displayName); // AlexEl operador de asignación nula ??= asigna un valor solo si la variable es actualmente nula:
String? username;
username ??= 'Anonymous';
print(username); // Anonymous
username ??= 'NewName';
print(username); // Sigue siendo Anonymous (no era nulo)Puedes encadenar el operador de acceso consciente de nulos ?. para propiedades anidadas:
String? city = user?.address?.city; // Seguro incluso si user o address es nullEstos operadores se combinan bien entre sí. Por ejemplo, podrías acceder a una propiedad que admite valores nulos y proporcionar un valor predeterminado:
String greeting = user?.name ?? 'Stranger';
// Si user es null O user.name es null, usa 'Stranger'El uso de estos operadores mantiene su código legible mientras mantiene la seguridad contra nulos en todo su programa.
Desafío
FácilVamos a construir un sistema de registro de invitados que demuestre cómo los operadores null-aware pueden hacer que tu código sea más limpio al manejar información opcional.
Organizarás tu código en dos archivos:
guest.dart: Define una claseGuestque represente a alguien que asiste a un evento. Algunos invitados proporcionan detalles completos, mientras que otros solo dan lo básico. Tu clase debe tener:- Un
String nameno nulable: cada invitado debe tener un nombre - Un
String? emailnulable: no todos proporcionan un correo electrónico - Un
String? dietaryPreferencenulable: algunos invitados no especifican necesidades dietéticas - Un constructor que tome
namecomo un parámetro requerido - Un método
getDisplayEmail()que devuelva el correo electrónico si está disponible, o'No email provided'usando el operador?? - Un método
assignDefaultDiet()que establezcadietaryPreferencea'Standard'solo si es actualmente nulo, usando el operador??= - Un método
getEmailDomain()que devuelva la longitud del correo electrónico usando?., onullsi no existe el correo electrónico - Un método
printBadge()que imprima la información de la credencial del invitado
- Un
main.dart: Importa tu clase de invitado y registra a tres invitados con diferentes niveles de información:- Crea un invitado llamado
'Alice', establece su correo electrónico a'alice@company.com'y su preferencia dietética a'Vegetarian' - Crea un invitado llamado
'Bob', establece solo su correo electrónico a'bob@email.org'(deja la preferencia dietética como nula) - Crea un invitado llamado
'Charlie'(deja tanto el correo electrónico como la preferencia dietética como nulos) - Llama a
assignDefaultDiet()en los tres invitados - Para cada invitado en orden, llama a
printBadge(), luego imprimeEmail length: [result]usandogetEmailDomain()
- Crea un invitado llamado
El método printBadge() debe imprimir en este formato:
=== Guest Badge ===
Name: [name]
Email: [getDisplayEmail()]
Diet: [dietaryPreference or "Not specified"]Observa cómo la preferencia dietética de Alice se mantiene como 'Vegetarian' porque ??= solo asigna cuando el valor es nulo, mientras que a Bob y Charlie se les asigna la dieta predeterminada 'Standard'.
Salida esperada:
=== Guest Badge ===
Name: Alice
Email: alice@company.com
Diet: Vegetarian
Email length: 17
=== Guest Badge ===
Name: Bob
Email: bob@email.org
Diet: Standard
Email length: 13
=== Guest Badge ===
Name: Charlie
Email: No email provided
Diet: Standard
Email length: nullHoja de referencia
Dart proporciona operadores sensibles a nulos para trabajar con valores que pueden ser nulos de forma más concisa.
El operador de coalescencia nula ?? devuelve el valor de la izquierda si no es nulo; de lo contrario, devuelve el valor de la derecha:
String? nickname;
String displayName = nickname ?? 'Guest';
print(displayName); // Guest
nickname = 'Alex';
displayName = nickname ?? 'Guest';
print(displayName); // AlexEl operador de asignación sensible a nulos ??= asigna un valor solo si la variable es actualmente nula:
String? username;
username ??= 'Anonymous';
print(username); // Anonymous
username ??= 'NewName';
print(username); // Still Anonymous (wasn't null)Puedes encadenar el operador de acceso sensible a nulos ?. para propiedades anidadas:
String? city = user?.address?.city; // Safe even if user or address is nullEstos operadores se pueden combinar entre sí:
String greeting = user?.name ?? 'Stranger';
// If user is null OR user.name is null, use 'Stranger'Pruébalo tú mismo
import 'guest.dart';
void main() {
// TODO: Crea un invitado llamado 'Alice'
// Establece su correo electrónico a 'alice@company.com'
// Establece su preferencia dietética a 'Vegetarian'
// TODO: Crea un invitado llamado 'Bob'
// Establece solo su correo electrónico a 'bob@email.org'
// Deja la preferencia dietética como null
// TODO: Crea un invitado llamado 'Charlie'
// Deja tanto el correo electrónico como la preferencia dietética como null
// TODO: Llama a assignDefaultDiet() en los tres invitados
// TODO: Para cada invitado en orden (Alice, Bob, Charlie):
// - Llama a printBadge()
// - Imprime 'Email length: [result]' usando getEmailDomain()
}
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
1Fundamentos de POO
Archivos externosLibrerías e importacionesIntroducción a la POOClases vs. ObjetosLa palabra clave thisMétodosVariables de instanciaConceptos básicos de constructoresResumen - Calculadora sencilla4Seguridad de nulos
Introducción a la seguridad de nulosNulables vs No nulablesLos operadores ? y !Palabra clave Late y Null SafetyOperadores Null-awareNull Safety en clasesResumen - Sistema de perfil de usuario7Clases abstractas e interfaces
Clases abstractasMétodos abstractosInterfaces en DartInterfaces implícitasImplementar vs. ExtenderInterfaces múltiplesRepaso - Calculadora de figuras10Colecciones y Genéricos
Visión general de List, Set y MapColecciones con seguridad de tiposClases genéricasMétodos genéricosRestricciones genéricasIterable e IteratorResumen - Almacenamiento genérico2Constructores en Dart
Constructor por defectoConstructores nombradosListas de inicializaciónConstructores constantesConstructores de fábricaConstructores de redireccionamientoResumen - Constructor de formas5Encapsulamiento
Miembros públicos vs. privadosLa convención del prefijo _Privacidad a nivel de libreríaProfundidad en Getters y SettersOcultamiento de informaciónResumen - Registros de estudiantes8Mixins
Introducción a los MixinsCreación de MixinsUso de múltiples MixinsPalabra clave on en MixinsMixin vs HerenciaMixin vs InterfazResumen - Sistema Animal11Métodos especiales
Sobrescritura de toString()Sobrescritura de hashCode y ==Interfaz ComparableMétodo call()Sobrescritura de noSuchMethodResumen - Colección personalizada14Patrones de diseño Parte 1
Introducción a los patrones de diseñoPatrón SingletonPatrón FactoryPatrón ObserverPatrón Strategy3Propiedades de clase
Miembros de instancia vs. estáticosCampos Final y ConstVariables LateMétodos y campos estáticosGetters y SettersResumen - Gestor de cuentas bancarias6Herencia
Herencia básicaLa palabra clave superSobrescritura de métodosLa anotación @overrideLa palabra clave final en clasesConstructores y herenciaResumen - Jerarquía de empleados9Polimorfismo
Fundamentos del polimorfismoPolimorfismo mediante interfacesComprobación de tipos en tiempo de ejecuciónLos operadores is y asPalabra clave covariantResumen - Procesador de pagos12POO Asíncrona
Futures y async/awaitFundamentos de StreamsStream ControllersConstructores asíncronosAsincronía en métodos de claseRepaso - Data Fetcher15Patrones de diseño Parte 2
Patrón CommandPatrón AdapterPatrón DecoratorPatrón Template MethodPatrón StatePatrón CompositePatrón Repository