Menu
Coddy logo textTech

Les opérateurs ? et !

Fait partie de la section Programmation Orientée Objet du Journey Dart de Coddy — leçon 25 sur 110.

Lorsque vous travaillez avec des types nullable, Dart fournit deux opérateurs essentiels pour accéder aux valeurs en toute sécurité. L'opérateur d'accès conditionnel (null-aware) ?. et l'opérateur d'assertion de non-nullité ! vous permettent de contrôler la manière dont vous gérez les valeurs potentiellement nulles.

L'opérateur ?. accède en toute sécurité aux propriétés ou aux méthodes d'une valeur nullable. Si la valeur est nulle, l'expression entière renvoie null au lieu de planter :

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

name = null;
print(name?.length);  // null (pas de crash !)

L'opérateur ! indique à Dart « Je suis certain que cette valeur n'est pas nulle. » Il convertit un type nullable en non-nullable, mais lève une erreur si la valeur est réellement nulle :

String? maybeName = 'Bob';
String definite = maybeName!;  // OK - nous affirmons qu'il n'est pas nul
print(definite.length);  // 3

String? empty = null;
// String crash = empty!;  // Erreur d'exécution ! La valeur était nulle

Utilisez ?. lorsque vous souhaitez gérer les valeurs nulles en toute sécurité. Utilisez ! uniquement lorsque vous êtes absolument certain qu'une valeur existe - peut-être après l'avoir vérifiée avec une instruction if ou lorsque vous savez que la logique garantit une valeur. L'utilisation excessive de ! va à l'encontre de l'objectif de la sécurité null et peut entraîner des plantages lors de l'exécution.

challenge icon

Défi

Facile

Construisons un système d'inventaire de produits qui démontre comment travailler en toute sécurité avec des valeurs nullables en utilisant les opérateurs ?. et !.

Vous allez créer deux fichiers pour organiser votre code :

  • product.dart : Définissez une classe Product qui représente un article dans l'inventaire. Certains produits ont des informations complètes, tandis que d'autres sont encore en cours de catalogage. Votre classe doit avoir :
    • Un String name non-nullable - chaque produit doit avoir un nom
    • Un double price non-nullable - chaque produit doit avoir un prix
    • Un String? description nullable - certains produits n'ont pas encore de description
    • Un String? category nullable - certains produits n'ont pas encore été catégorisés
    • Un constructeur qui prend name et price comme paramètres obligatoires
    • Une méthode getDescriptionLength() qui retourne la longueur de la description en utilisant ?., ou null s'il n'y a pas de description
    • Une méthode getCategoryUppercase() qui retourne la catégorie en majuscules en utilisant ! - cette méthode suppose que la catégorie a été définie
    • Une méthode displayProduct() qui affiche les informations du produit, montrant "No description" quand la description est nulle et "Uncategorized" quand la catégorie est nulle
  • main.dart : Importez votre classe de produit et démontrez les deux opérateurs :
    • Créez un produit nommé 'Laptop' avec le prix 999.99, puis définissez sa description sur 'High-performance computing device' et sa catégorie sur 'Electronics'
    • Créez un produit nommé 'Mystery Item' avec le prix 49.99 (laissez la description et la catégorie à null)
    • Pour le Laptop : appelez displayProduct(), affichez "Description length: [length]" en utilisant getDescriptionLength(), et affichez "Category: [uppercase]" en utilisant getCategoryUppercase()
    • Pour le Mystery Item : appelez displayProduct() et affichez "Description length: [length]" en utilisant getDescriptionLength() (cela affichera null)

La méthode displayProduct() doit afficher les informations dans ce format :

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

Sortie attendue :

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

Aide-mémoire

L'opérateur d'accès sécurisé (null-aware) ?. accède en toute sécurité aux propriétés ou méthodes sur des valeurs nullables. Si la valeur est nulle, il renvoie null au lieu de lever une erreur :

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

name = null;
print(name?.length);  // null (pas de plantage !)

L'opérateur d'assertion de non-nullité ! convertit un type nullable en non-nullable. Utilisez-le uniquement lorsque vous êtes certain que la valeur n'est pas nulle, car il lèvera une erreur d'exécution si la valeur est réellement nulle :

String? maybeName = 'Bob';
String definite = maybeName!;  // OK - affirme qu'elle n'est pas nulle
print(definite.length);  // 3

String? empty = null;
// String crash = empty!;  // Erreur d'exécution !

Utilisez ?. pour une gestion gracieuse des valeurs nulles et ! uniquement lorsque vous êtes absolument certain qu'une valeur existe.

Essayez vous-même

import 'product.dart';

void main() {
  // TODO: Créer un produit nommé 'Laptop' avec le prix 999.99
  // Ensuite, définir sa description sur 'High-performance computing device'
  // Et définir sa catégorie sur 'Electronics'
  
  // TODO: Créer un produit nommé 'Mystery Item' avec le prix 49.99
  // Laisser la description et la catégorie à null
  
  // TODO: Pour le Laptop :
  // - Appeler displayProduct()
  // - Afficher "Description length: [length]" en utilisant getDescriptionLength()
  // - Afficher "Category: [uppercase]" en utilisant getCategoryUppercase()
  
  // TODO: Pour le Mystery Item :
  // - Appeler displayProduct()
  // - Afficher "Description length: [length]" en utilisant getDescriptionLength()
}
quiz iconTestez-vous

Cette leçon comprend un petit quiz. Commencez la leçon pour y répondre et suivre votre progression.

Toutes les leçons de Programmation Orientée Objet