10
votes

Quelle est la méthode recommandée dans Dart: affirme ou lance des erreurs

Dart fait explicitement une distinction entre Error, qui signale un problème dans la logique de votre code et ne devrait jamais se produire et ne devrait jamais être intercepté et les exceptions qui signalent un problème basé sur les données d'exécution.

J'aime vraiment cette distinction mais je me demande quand puis-je utiliser les fonctions assert() ?


0 commentaires

4 Réponses :


4
votes

Comme les asserts sont ignorées en mode production, vous devez les utiliser pour effectuer des tests initiaux de votre logique de code en mode débogage:

Dans le code de production, les assertions sont ignorées et les arguments à affirmer ne sont pas évalués.


1 commentaires

Oui, c'est clair, la question est de savoir pourquoi utiliser des assertions si nous convenons qu'elles signalent un état d'erreur qui ne devrait vraiment pas se produire. La seule raison pour laquelle je vois si c'est pour l'optimisation si c'est une fonction qui est appelée très souvent et que vous voulez éliminer le mode de libération conditionnelle de check inn.



1
votes

Quand les assertions fonctionnent-elles exactement? Cela dépend des outils et du framework que vous utilisez:

Flutter active les assertions en mode débogage.
Les outils de développement uniquement tels que dartdevc activent généralement les assertions par défaut.
Certains outils, tels que dart et dart2js, prennent en charge les assertions via un indicateur de ligne de commande: --enable-asserts.
Dans le code de production, les assertions sont ignorées et les arguments à affirmer ne sont pas évalués.

Reportez-vous: https://dart.dev/guides/language/language-tour#assert


1 commentaires

Oui, c'est clair, la question est de savoir pourquoi utiliser des assertions si nous convenons qu'elles signalent un état d'erreur qui ne devrait vraiment pas se produire. La seule raison pour laquelle je vois si c'est pour l'optimisation si c'est une fonction qui est appelée très souvent et que vous voulez éliminer le mode de libération conditionnelle de check inn.



8
votes

Les assertions sont des moyens d'exécuter du code utile uniquement en développement, sans entraver les performances du mode release - généralement pour éviter les mauvais états causés par une fonctionnalité manquante dans le système de types.

Par exemple, seules les assertions peuvent être utilisées pour faire de la programmation défensive et offrir un constructeur const.

Nous pouvons faire:

assert(someVeryExpensiveCheck());

mais ne peut pas faire:

class Foo {
  const Foo() { throw 42; }
}

De même, certains contrôles de santé sont relativement coûteux.

Dans le contexte de Flutter, par exemple, vous voudrez peut-être parcourir l'arborescence des widgets pour vérifier quelque chose sur les ancêtres d'un widget. Mais c'est coûteux, pour quelque chose d'utile uniquement pour un développeur.

Faire cette vérification à l'intérieur d'une assert permet à la fois les performances en version et l'utilité en développement.

class Foo {
  const Foo(): assert(false);
}


3 commentaires

Très bons points. J'attends juste si peut-être de l'équipe Dart une réponse vient :-)


Donc, vous pourriez dire toujours aller pour l'erreur sauf si le chèque est cher


Non, je ne dirais pas cela, mais c'est une opinion. Je ne pense pas qu'il existe une recommandation qui puisse convenir à tout le monde ici.



2
votes

Contexte
  • Dans Dart, une Exception concerne un mauvais état attendu qui peut se produire lors de l'exécution. Étant donné que ces exceptions sont attendues, vous devez les attraper et les gérer de manière appropriée.
  • Une Error , en revanche, est destinée aux développeurs qui utilisent votre code. Vous lancez une erreur pour leur faire savoir qu'ils utilisent mal votre code. En tant que développeur utilisant une API, vous ne devez pas détecter les erreurs. Vous devriez les laisser planter votre application. Que le crash soit un message pour vous que vous devez aller découvrir ce que vous faites de mal.
  • Une assert est similaire à une Error en ce sens qu'elle sert à signaler des états défectueux qui ne devraient jamais se produire. La différence est que les assertions ne sont vérifiées qu'en mode débogage. Ils sont complètement ignorés en mode production.

En savoir plus sur la différence entre Exception et Error ici .

Ensuite, voici quelques exemples pour voir comment chacun est utilisé dans le code source Flutter.

Exemple de lancement d'une exception

Cela vient de platform_channel.dart dans le référentiel Flutter :

OverlayEntry({
  @required this.builder,
  bool opaque = false,
  bool maintainState = false,
}) : assert(builder != null),
      assert(opaque != null),
      assert(maintainState != null),
      _opaque = opaque,
      _maintainState = maintainState;

L' MissingPluginException est ici un mauvais état planifié qui pourrait se produire. Si cela se produit, les utilisateurs de l'API du canal de plate-forme doivent être prêts à gérer cela.

Exemple de lancement d'une erreur

Cela provient de artifacts.dart dans le référentiel flutter_tools .

TargetPlatform _currentHostPlatform(Platform platform) {
  if (platform.isMacOS) {
    return TargetPlatform.darwin_x64;
  }
  if (platform.isLinux) {
    return TargetPlatform.linux_x64;
  }
  if (platform.isWindows) {
    return TargetPlatform.windows_x64;
  }
  throw UnimplementedError('Host OS not supported.');
}

Tout d'abord, toutes les possibilités sont épuisées, puis l'erreur est renvoyée. Cela devrait être théoriquement impossible. Mais s'il est lancé, il s'agit soit d'un signe pour l'utilisateur de l'API que vous l'utilisez mal, soit d'un signe pour le responsable de l'API qu'il doit gérer un autre cas.

Exemple d'utilisation d'assertions

Cela vient de overlay.dart dans le référentiel Flutter :

@optionalTypeArgs
Future<T?> _invokeMethod<T>(String method, { required bool missingOk, dynamic arguments }) async {
  assert(method != null);
  final ByteData? result = await binaryMessenger.send(
    name,
    codec.encodeMethodCall(MethodCall(method, arguments)),
  );
  if (result == null) {
    if (missingOk) {
      return null;
    }
    throw MissingPluginException('No implementation found for method $method on channel $name');
  }
  return codec.decodeEnvelope(result) as T;
}

Le modèle dans le code source de Flutter consiste à utiliser les assertions libéralement dans la liste d'initialisation des constructeurs. Ils sont beaucoup plus courants que les erreurs.

Sommaire

Lorsque je lis le code source de Flutter, utilisez des assertions comme vérifications préliminaires dans la liste d'initialiseurs du constructeur et lancez des erreurs en dernier recours dans le corps des méthodes. Bien sûr, ce n'est pas une règle dure et rapide pour autant que je puisse le voir, mais cela semble correspondre au modèle que j'ai vu jusqu'à présent.


0 commentaires