32 votes

Je veux utiliser des paramètres nommés dans Dart pour plus de clarté. Comment dois-je les gérer ?

TL;DR : Les paramètres nommés sont facultatifs en raison de l'utilisation de la fonction un choix de conception conscient . À défaut d'un support linguistique officiel, existe-t-il un moyen d'imposer (et d'informer) les arguments nommés requis ?


Je trouve extrêmement utile d'utiliser des paramètres nommés lors de la définition d'une classe. Prenez, par exemple, un Ability dans un MMORPG :

class Ability {

  final name;
  final effectDuration;
  final recast;            // wait time until next use
  // ...
}

effectDuration y recast Les deux portent le même type d'information (c'est-à-dire la durée du temps) et sont probablement représentés par le même type de données. Il est facile de confondre quel chiffre va où. Cependant, il s'agit de deux informations vitales pour l'exactitude de l'objet, elles ne peuvent donc pas manquer lors de l'instanciation.

Je pourrais simplement casser le programme via un try-catch pour faire respecter l'exigence de ces paramètres, mais cela ne semble pas amusant pour quelqu'un qui utilise la classe et qui n'a aucune idée (à part lire les docs et comprendre intuitivement ce que fait la classe) qu'ils sont requis.

Existe-t-il un moyen de faire respecter l'exigence de certains paramètres nommés tout en parvenant à informer l'appelant de cette exigence et/ou à l'aider à l'utiliser correctement ?

51voto

Günter Zöchbauer Points 21340

Le site méta fournit un @required qui est prise en charge par DartAnalyzer.

Flutter l'utilise beaucoup et fournit @required directement de import 'package:flutter/foundation.dart'

foo({@required String name}) {...}

foo(); // results in static warning

@required ne vérifie pas si la valeur passée est null ou non, mais seulement qu'une valeur a été effectivement transmise sur le site d'appel. Pour vérifier null vous pouvez également utiliser assert() pour vérifier les valeurs passées

class Ability {
  Ability(this.name, this.effectDuration, this.recast) : assert(name != null), assert(effectDuration != null), assert(recast != null);
  final name;
  final effectDuration;
  final recast;            // wait time until next use
  // ...
}

19voto

rmtmckenzie Points 10854

Si, il y en a une !

Voici un exemple :

class Ability {
  final String name;
  final Duration effectDuration;
  final bool recast;

  Ability({
    @required this.name,
    this.effectDuration = new Duration(seconds: 1),
    this.recast = false,
  }): 
    assert(name != null),
    assert(effectDuration != null);
}

Vous n'avez pas besoin d'affirmer que name n'est pas égal à null, mais cela pourrait vous être utile.

8voto

Suragch Points 197

Bien que vous puissiez utiliser le flutter foundation comme décrit dans la réponse acceptée, lorsque je travaille avec des classes de modèles qui n'ont pas besoin de connaître Flutter, je préfère utiliser le package méta directement. De cette façon, il ne crée pas de dépendance inutile au framework. Cela vous permet de partager le code Dart même en dehors de Flutter.

Ajouter méta a pubspec.yaml :

dependencies:
  meta: ^1.1.7

Importez-le dans votre fichier de classe :

import 'package:meta/meta.dart';

Utilisez le @required dans votre code :

class Person {
  String name;
  int age;

  Person({@required this.name, this.age,});
}

Alors name est un paramètre obligatoire, mais age ne l'est pas.

final person = Person(name: 'Bob');

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X