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ácilConstruyamos un sistema de registro de invitados que demuestre cómo los operadores conscientes de valores nulos 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 todos sus datos, mientras que otros solo dan la información básica. Tu clase debe tener:- Un
String nameno anulable: todo invitado debe tener un nombre - Un
String? emailanulable: no todos proporcionan un correo electrónico - Un
String? dietaryPreferenceanulable: algunos invitados no especifican sus necesidades alimentarias - Un constructor que reciba
namecomo parámetro obligatorio - Un método
getDisplayEmail()que devuelva el correo electrónico si está disponible, o'No email provided'mediante el operador?? - Un método
assignDefaultDiet()que establezcadietaryPreferenceen'Standard'solo si actualmente es null, mediante el operador??= - Un método
getEmailDomain()que devuelva la longitud del correo electrónico usando?., onullsi no existe ningún 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 distintos niveles de información:- Crea un invitado llamado
'Alice', establece su correo electrónico en'alice@company.com'y su preferencia alimentaria en'Vegetarian' - Crea un invitado llamado
'Bob', establece únicamente su correo electrónico en'bob@email.org'(deja la preferencia alimentaria como null) - Crea un invitado llamado
'Charlie'(deja tanto el correo electrónico como la preferencia alimentaria como null) - Llama a
assignDefaultDiet()en los tres invitados - Para cada invitado, en orden, llama a
printBadge()y después imprimeEmail length: [result]usandogetEmailDomain()
- Crea un invitado llamado
El método printBadge() debe imprimir con este formato:
=== Guest Badge ===
Name: [name]
Email: [getDisplayEmail()]
Diet: [dietaryPreference or "Not specified"]Observa cómo la preferencia alimentaria de Alice sigue siendo 'Vegetarian' porque ??= solo asigna un valor cuando el valor es null, 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: nullPrué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 RepositoryPractica por tu cuenta: Compilador de Dart online