web-dev-qa-db-fra.com

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 n choix de conception conscient . À moins d'avoir une prise en charge des langues officielles, existe-t-il un moyen d'appliquer (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 et recast portent tous deux le même type d'information (c'est-à-dire la durée) et sont probablement représentés par le même type de données. Il est facile de mélanger quel numéro va où. Cependant, ce sont deux informations vitales pour l'exactitude de l'objet, donc elles ne peuvent pas être manquantes lors de l'instanciation.

Je pourrais simplement casser le programme via un try-catch pour imposer l'exigence de ces paramètres, mais cela ne semble pas amusant pour quelqu'un qui utilise la classe et n'a aucune idée (à court de lire les documents et de 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?

11
Kafeaulait

Le package meta fournit une annotation @required Prise en charge par DartAnalyzer.

Flutter l'utilise beaucoup et fournit @required Directement à partir de import 'package:flutter/foundation.Dart'

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

foo(); // results in static warning

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

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
  // ...
}    
23
Günter Zöchbauer

Oui il y a!

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 à affirmer que le nom n'est pas égal à null, mais il pourrait vous être utile.

4
rmtmckenzie

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

Ajoutez meta à pubspec.yaml :

dependencies:
  meta: ^1.1.7

Importez-le dans votre fichier de classe:

import 'package:meta/meta.Dart';

Utilisez le @required annotation dans votre code:

class Person {
  String name;
  int age;

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

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

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