De lever des exceptions à la Scala, qu'est-ce que la “règle officielle”
Je suis à la suite de la Scala de cours sur Coursera.
J'ai commencé à lire la Scala livre de Odersky ainsi.
Ce que j'entends souvent, c'est que ce n'est pas une bonne idée de lancer des exceptions dans les langages fonctionnels, parce qu'il rompt le flux de contrôle et nous avons l'habitude de revenir un, Soit avec l'Échec ou le Succès.
Il semble également que la Scala 2.10 fournira l'essai qui va dans cette direction.
Mais dans le livre et le cours, Martin Odersky ne semble pas pour le dire (au moins pour l'instant) que les exceptions sont mauvais, et qu'il les utilise beaucoup.
J'ai aussi remarqué que les méthodes d'affirmer /besoin...
Enfin je suis un peu confus, parce que j'aimerais suivre les meilleures pratiques, mais elles ne sont pas claires et la langue semble aller dans les deux sens...
Quelqu'un peut-il m'expliquer ce que je dois utiliser dans quel cas?
- Je pense que le plus vous biaisée de pur fonctionnel haskell/scalaz côté, plus vous allez utiliser/Essayer. Passer d'exceptions à l'un des deux est un continuum et il est difficile de dire où est la limite entre eux.
- Bonne question, j'ai également été surpris par lui, en recourant à l'exception de jeter toute la place. Mais alors, il est vrai, de la
Nothing
type est une sorte de élégant pour le polymorphisme. - J'ai posé une question similaire: stackoverflow.com/questions/13012149/... (merci pour om-nom-nom pour le lien)
Vous devez vous connecter pour publier un commentaire.
La directive de base consiste à utiliser les exceptions pour quelque chose de vraiment exceptionnel**. Pour un "ordinaire" de l'échec, il est de loin préférable d'utiliser
Option
ouEither
. Si vous êtes l'interfaçage avec Java, où des exceptions sont levées lorsque quelqu'un éternue dans le mauvais sens, vous pouvez utiliserTry
pour vous garder en sécurité.Prenons quelques exemples.
Supposons que vous avez une méthode qui récupère quelque chose à partir d'une carte. Ce qui pourrait aller mal? Eh bien, quelque chose de dramatique et dangereux, comme un
erreur de segmentation* débordement de pile, ou quelque chose d'attendu comme l'élément n'est pas trouvé. Vous laisserais leerreur de segmentationde débordement de pile lancer une exception, mais si vous vous contentez de vous ne trouvez pas un élément, pourquoi pas le retour d'unOption[V]
au lieu de la valeur ou d'une exception (ounull
)?Maintenant, supposons que vous écrivez un programme où l'utilisateur doit entrer un nom de fichier. Maintenant, si vous n'êtes pas aller juste pour instantanément caution sur le programme quand quelque chose va mal, une
Either
est le chemin à parcourir:Maintenant, supposons que vous souhaitez analyser une chaîne avec un espace délimité par des numéros.
Donc, vous avez trois façons (au moins) pour faire face aux différents types de panne:
Option
puisqu'on a fait /n'a pas, dans le cas où ne fonctionne pas le comportement attendu, pas choquant et inquiétant, l'échec;Either
pour quand les choses peuvent fonctionner ou pas (ou, vraiment, tous les cas où vous avez deux options mutuellement exclusives) et que vous voulez économiser quelques informations sur ce qui s'est passé; etTry
lorsque vous ne voulez pas l'ensemble des maux de tête de la manipulation d'exception-vous, mais encore besoin de faire l'interface avec le code qui est exception-heureux.D'ailleurs, exceptions faites de bons exemples, vous les trouverez le plus souvent dans un livre ou d'un matériel d'apprentissage qu'ailleurs, je pense que: exemples classiques sont très souvent incomplètes, ce qui signifie que les problèmes graves qui, normalement, serait empêché par une conception rigoureuse devrait plutôt être marqué par la levée d'une exception.
*Edit: Segmentation crash de la JVM et ne devrait jamais se produire quel que soit le bytecode; même une exception ne sera pas vous aider alors. Je voulais dire débordement de la pile.
**Edit: les Exceptions (sans une trace de la pile) sont également utilisés pour le contrôle de flux dans Scala--ils sont en fait assez un mécanisme efficace, et ils permettent à des choses comme la bibliothèque défini
break
consolidés et unreturn
que des retours de votre méthode, même si le contrôle a effectivement passé dans une ou plusieurs fermetures. Pour la plupart, vous ne devriez pas vous inquiéter à propos de ce vous-même, sauf à réaliser que la capture de tousThrowable
s n'est pas une super idée car vous pourriez attraper une de ces flux de contrôle exceptions par erreur.def f(xs: Seq[Int]): Int = { xs.foreach(i => if (i>10) return i); 0 }
, quereturn
n'est pas un réelreturn
parce que quand vous êtes dans leforeach
vous êtes réellement à l'intérieur d'une méthode complètement différente! Pour revenir sur le, Scala effectivement déclenche une exception avec la valeur de retour au lieu d'une trace de la pile, et l'attrape avec unetry
bloc placé autour du contenu def
.scala.runtime.NonLocalReturnControl
, une sous-classe deControlThrowable
.Donc, c'est un de ces endroits où Scala spécifiquement des métiers hors fonctionnelle pureté pour faciliter la transition à partir de/à l'interopérabilité avec d'anciennes langues et environnements, plus précisément Java. Fonctionnelle, la pureté est brisé par des exceptions, comme ils cassent l'intégrité référentielle et il est impossible à la raison equationally. (Bien sûr, la non-terminaison de récurrences faire de même, mais peu de langues sont prêts à appliquer les restrictions qui allait faire de ces impossible.) Pour garder la fonctionnelle de la pureté, vous utilisez l'Option/Peut-être/De/Essayer/de Validation, tous les codent de la réussite ou de l'échec comme une referentially-transparent type, et utiliser les différentes fonctions d'ordre supérieur qu'ils fournissent ou les langues spéciales monade syntaxe pour rendre les choses plus claires. Ou, en Scala, vous pouvez simplement décider d'abandonner la fonctionnelle de la pureté, sachant qu'il pourrait rendre les choses plus facile, à court terme, mais plus difficile à la longue. Ceci est similaire à l'utilisation de "null" dans la Scala, ou mutable collections, ou local "var"s. Légèrement honteux, et ne faites pas grand-chose, mais tout le monde, sous la date limite.
Nothing
bottom-type, je ne pense pas que quelque chose est "cassé". Si votre code est purement fonctionnelle, les exceptions ne devrait pas poser de problème, non? Elles ne deviennent difficiles lorsque les effets secondaires sont impliqués.