Opérateurs de test de type Dart

Aperçu des trois opérateurs (as /is/is!)

OpérateurDescription de fonction
asConversion de type forcée ; sert aussi à définir des alias de bibliothèques
isVérification de type : renvoie true si l’objet correspond au type spécifié
is!Vérification de type : renvoie true si l’objet ne correspond pas au type spécifié

Condition de validation de obj is T : l’objet obj implémente ou hérite du type T (inclut les classes parentes, interfaces et types nullables).

Exemple : N'importe quel objet is Object? renverra toujours true.

Opérateur is

Vérification de type sécurisée

Vérifie le type de l’objet à l’exécution ; si le résultat vaut true, vous pouvez utiliser l’objet directement comme ce type dans le bloc de code, sans conversion manuelle. Si l’objet vaut null ou que le type ne correspond pas, il renvoie false sans lever d’exception.

L’exemple ci-dessous utilise des objets de classe. Si vous n’avez pas encore étudié les classes, voyez-les simplement comme des modèles servant à créer des données.

class Person {
  String firstName = '';
}

class Employee extends Person {}

void main() {
  dynamic employee = Employee();

  // Vérification de type avec is
  if (employee is Person) {
    // À l'intérieur de la condition, employee est automatiquement typé Person
    employee.firstName = "Jack";
    print(employee.firstName); // Affiche Jack
  }

  dynamic emptyObj = null;
  if (emptyObj is Person) {
    // Ne s'exécute pas, null ne correspond pas à Person
    print("Correspondance réussie");
  }
}Langage du code : Dart (dart)

Ce code définit une classe Person, puis une classe Employee qui hérite de Person.

Dans le code, is permet de vérifier si un objet est de type Person. Si c’est le cas, vous pouvez l’utiliser directement comme Person dans le bloc {}. Cela vient du fait que dynamic employee = Employee(); utilise un type dynamique.

Dans le second exemple dynamic emptyObj = null;, la valeur est null, donc emptyObj is Person vaut false et le code du bloc {} ne s’exécute pas.

Opérateur is!

Vérification de type inverse

Syntaxe :

variable is! type

C’est équivalent à l’opérateur is suivi d’une négation.

Équivaut à !(variable is type) : vérifie que l’objet n’est pas du type cible.

Voici un exemple :

class Person {
  String name = '';
}

void main() {
  dynamic obj = "texte";
  if (obj is! Person) {
    print("obj n'est pas de type Person");
  }
}Langage du code : Dart (dart)

Cet exemple exécute le code du bloc et affiche « obj n’est pas de type Person », car obj n’est pas une instance créée à partir du modèle Person.

Opérateur as

Conversion de type forcée

Utilisation :

(variable as typeCible).propriété/méthodeLangage du code : JavaScript (javascript)

N’utilisez cet opérateur seulement si vous êtes sûr à 100 % que l’objet est du type cible. Sinon, une exception d’exécution sera levée. Pour la robustesse du programme, évitez de l’utiliser excessivement.

class Teacher {
  String name = '';
}

void main() {
  dynamic jason = Teacher();
  // Conversion forcée vers Teacher pour accéder à la propriété
  (jason as Teacher).name = "Jason";
  print((jason as Teacher).name); // Jason
}Langage du code : Dart (dart)

Cet exemple affiche Jason

Nous créons directement une instance Teacher avec dynamic jason = Teacher();, nous pouvons donc garantir à 100 % qu’il s’agit d’un Teacher, d’où l’absence d’erreur ici.

Le code suivant générera une erreur.

class Teacher {
  String name = '';
}

class Car {
  String name = '';
}

void main() {
  dynamic jason = Teacher();
  
  // Conversion forcée vers Car pour accéder à la propriété
  (jason as Car).name = "Jason";//❌erreur
  print((jason as Car).name); //❌erreur
}Langage du code : Dart (dart)

L’erreur survient car jason est initialement une instance Teacher, mais nous essayons de la convertir de force en Car.

D:\dartdemo\firstdart>dart run
Building package executable...
Built firstdart:firstdart.
Unhandled exception:
type 'Teacher' is not a subtype of type 'Car' in type cast
#0      main (file:///D:/dartdemo/firstdart/bin/firstdart.dart:12:10)
#1      _delayEntrypointInvocation.<anonymous closure> (dart:isolate-patch/isolate_patch.dart:314:19)
#2      _RawReceivePort._handleMessage (dart:isolate-patch/isolate-patch.dart:193:12)Langage du code : PHP (php)

Comparaison essentielle entre as et is

// Écriture 1 : conversion forcée avec as
(employee as Person).firstName = 'Bob';

// Écriture 2 : vérification préalable avec is
if (employee is Person) {
  employee.firstName = 'Bob';
}Langage du code : JavaScript (javascript)

Comportement quand employee vaut null ou n’est pas de type Person :

  • Version as : l’exception CastError est levée et le programme plante ;
  • Version is : le bloc if n’est pas exécuté, pas d’erreur ni d’action.

Même si le code est un peu plus long, privilégiez la méthode avec is car elle assure une meilleure robustesse du programme.

Second usage de as

Second usage de as

as ne sert pas uniquement à la conversion de type : il permet de définir un alias pour une bibliothèque lors de l’importation

import 'dart:math' as math;

void main() {
  // Appel de classes/méthodes via l'alias de bibliothèque
  print(math.pi); // Affiche 3.141592653589793
}Langage du code : JavaScript (javascript)

Exemple complet final

class Animal {}
class Cat extends Animal {}

void main() {
  dynamic obj = Cat();

  // 1. Vérification avec is
  if (obj is Animal) {
    print("obj est de type Animal");
  }

  // 2. Vérification inverse avec is!
  if (obj is! String) {
    print("obj n'est pas une chaîne de caractères");
  }

  // 3. Conversion forcée avec as
  Animal a = obj as Animal;

  // Exemple erroné qui cause un plantage
  dynamic str = "hello";
  // Animal error = str as Animal; // Déclenche CastError
}Langage du code : JavaScript (javascript)

Laisser un commentaire

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