Opérateurs de cascade Dart

Il existe deux syntaxes de cascade : .. et ?..

Réaliser plusieurs affectations de propriétés et appels de méthodes consécutifs sur un même objet, ce qui évite les variables temporaires et rend le code plus fluide et cohérent.

La syntaxe de cascade n’est pas un opérateur, c’est un sucre syntaxique propre à Dart.

1. Cascade classique ..

À utiliser lorsque l’objet est garanti non nul

Toutes les opérations .. s’appliquent à l’objet d’origine au tout début, les valeurs de retour de chaque méthode sont ignorées.

Exemple officiel

import 'dart:ui';

void main() {
  // Écriture en cascade
  var paint = Paint()
    ..color = Colors.black
    ..strokeCap = StrokeCap.round
    ..strokeWidth = 5.0;

  // Écriture équivalente sans cascade (répétition du nom de variable)
  var paint2 = Paint();
  paint2.color = Colors.black;
  paint2.strokeCap = StrokeCap.round;
  paint2.strokeWidth = 5.0;
}Langage du code : JavaScript (javascript)

Cet exemple importe la bibliothèque dart:ui spécifique à Flutter, utilisable uniquement dans un projet Flutter. Ce tutoriel porte sur Dart pur, vous pouvez simplement comprendre la syntaxe ci-dessus. L’exemple suivant utilise une classe native pure Dart : StringBuffer.

Classe de manipulation de chaînes : StringBuffer

void main() {
  // Syntaxe de cascade
  var sb = StringBuffer()
    ..write("Hello ")
    ..write("FoxDevelop.com ")
    ..writeln("Cascade");

  print(sb.toString());

  // Version équivalente sans cascade
  var sb2 = StringBuffer();
  sb2.write("Hello ");
  sb2.write("FoxDevelop.com ");
  sb2.writeln("Cascade");
  print(sb2.toString());
}Langage du code : PHP (php)

Résultat d’exécution

D:\dartdemo\firstdart>dart run
Building package executable...
Built firstdart:firstdart.
Hello FoxDevelop.com Cascade

Hello FoxDevelop.com CascadeLangage du code : CSS (css)

La syntaxe ci-dessus s’utilise quand vous êtes certain que vos objets paint, sb, sb2 ne valent jamais null : elle permet d’affecter rapidement des valeurs sans répéter le nom de l’objet. En revanche, si l’objet est nul, une erreur survient immédiatement.

void main() {

  var sb = null
    ..write("Hello ")
    ..write("FoxDevelop.com ")
    ..writeln("Cascade");

  print(sb.toString());
}Langage du code : JavaScript (javascript)

C’est pourquoi une seconde variante existe, présentée ci-dessous.

2. Cascade sécurisée contre les null ?..

Si l’objet vaut null, toute la chaîne de cascade n’est pas exécutée, ce qui évite l’erreur de pointeur nul. Seul le premier opérateur de chaîne utilise ?.., les suivants prennent directement ...

void main() {

  var sb = null
    ?..write("Hello ")
    ..write("FoxDevelop.com ")
    ..writeln("Cascade");

  print(sb.toString());
}Langage du code : Dart (dart)

Voyez attentivement le point d’interrogation devant ?..write(« Hello « )

Une nouvelle compilation se déroule sans problème

D:\dartdemo\firstdart>dart run
Building package executable...
Built firstdart:firstdart.
nullLangage du code : CSS (css)

Aucune erreur ne survient

Voici l’exemple officiel : retenez uniquement la forme syntaxique.

// Début par ?.., ensuite uniquement ..
document.querySelector('#confirm')
  ?..textContent = 'Confirm'
  ..classList.add('important')
  ..onClick.listen((e) => window.alert('Confirmed!'))
  ..scrollIntoView();

// Version décomposée sécurisée contre les null équivalente
final button = document.querySelector('#confirm');
button?.textContent = 'Confirm';
button?.classList.add('important');
button?.onClick.listen((e) => window.alert('Confirmed!'));
button?.scrollIntoView();Langage du code : JavaScript (javascript)

Cascade imbriquée

final addressBook = (AddressBookBuilder()
      ..name = 'jenny'
      ..email = 'jenny@example.com'
      // Cascade séparée pour l’objet interne PhoneNumberBuilder
      ..phone = (PhoneNumberBuilder()
            ..number = '415-555-0100'
            ..label = 'home')
          .build())
    .build();Langage du code : PHP (php)

L’attribut phone est un objet instancié par PhoneNumberBuilder() auquel on affecte des valeurs.

Points d’attention

La cascade ne peut s’appliquer que sur une instance d’objet ; si elle suit une méthode retournant void, une erreur de compilation apparaît.

var sb = StringBuffer();
sb.write('foo') // write renvoie void
  ..write('bar'); // Erreur : void ne possède pas de méthode writeLangage du code : Dart (dart)

Ici nous avons d’abord créé une instance StringBuffer nommée sb

Mais la ligne se termine par un point-virgule avant d’appeler write sur sb ; comme write retourne void, il est impossible de chaîner un ..write derrière, à moins que write renvoie une instance d’objet.

Écriture correcte

var sb = StringBuffer()
  ..write('foo')
  ..write('bar');Langage du code : Dart (dart)

Synthèse

  1. .. ramène systématiquement à l’objet racine initial à chaque opération, sans récupérer la valeur renvoyée par les méthodes. Cela correspond au chaînage présent dans d’autres langages comme JavaScript.
  2. ?.. est la cascade sécurisée contre les null pour éviter les erreurs quand l’objet vaut null. Il ne s’utilise qu’en début de chaîne : si le premier appel s’exécute, l’objet n’est pas nul, donc les opérateurs suivants n’ont pas besoin de ?..
  3. Les cascades imbriquées sont autorisées
  4. Impossible de placer une cascade après une méthode qui retourne void
  5. .. n’est pas un opérateur mais un sucre syntaxique Dart
Qu’est-ce qu’un sucre syntaxique ?

Le sucre syntaxique est une forme abrégée légère proposée par un langage de programmation pour une même logique sous-jacente au moment de l’analyse syntaxique ; il n’apporte aucune nouvelle capacité au langage. Le compilateur ou interpréteur transforme automatiquement cette syntaxe abrégée en code standard équivalent avant de générer le code intermédiaire.

Laisser un commentaire

Votre adresse e-mail ne sera pas publiée. Les champs obligatoires sont indiqués avec *