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?
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
// ...
}
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.
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');