2010-08-23 5 views
6

J'écris le constructeur pour ma classe "principale". La première chose à faire est d'appeler une méthode pour utiliser commons-cli pour analyser la ligne de commande. Si la méthode parseOptions renvoie la valeur false, une erreur s'est produite et le constructeur doit quitter.Retour anticipé d'un constructeur Scala

J'ai essayé d'écrire le code suivant

if (!parseOptions(args)) return 

mais le compilateur se plaint que j'ai une « déclaration de retour définition de la méthode à l'extérieur ».

court d'appeler System.exit(1) ou inverser le booléen (et mettre tout le reste de ma logique dans l'instruction if, est-il possible de revenir « début » d'un constructeur?

Je suppose que je pourrais avoir la parseOptions méthode jeter un IllegalArgumentException et attraper dans mon objet Main.

Merci.

+1

Bien que je suis d'accord avec les autres réponses que aucun constructeur devrait revenir normalement si elle n'a pas pu pour mettre l'instance dans un état qui satisfait les invariants de sa classe, je me demande pourquoi vous êtes opposé à l'utilisation de 'if'? –

+0

Si j'ai plusieurs conditions qui peuvent toutes entraîner un retour anticipé, je finirai par une cascade 'if' à plusieurs niveaux. – Ralph

+0

Alors? Si c'est la logique de votre constructeur, c'est la logique de votre constructeur. Il est généralement conseillé de ne pas avoir beaucoup de logique complexe dans vos constructeurs. Idéalement, ils "notent" simplement les valeurs qui composent l'état/la valeur de l'instance. –

Répondre

11

est-il possible de revenir « début » d'un constructeur

Non, mais dans votre cas, il sonne comme une mauvaise conception, de toute façon.

Si la méthode ParseOptions retourne false, une erreur est survenue

Dans ce cas, le constructeur doit lancer une exception, ne retourne normalement.

+0

Après avoir repensé (et l'avoir implémenté avec 'IllegalArgumentException'), je suis d'accord qu'une mauvaise analyse de ligne de commande mérite une exception. – Ralph

12

ne pas essayer de faire un retour rapide/prématuré, cela rend votre code plus difficile plus complexe, car les effets secondaires du retour peuvent être h ard à comprendre. Au lieu de cela, utilisez une exception pour signaler que quelque chose ne va pas.

Vous pouvez utiliser require dans le constructeur. Cela ne retourne pas. Mais il semble que lancer une exception correspond mieux à sa situation.

Comme dans:

class MyTest(
private var myValue: Int){ 

    require(myValue > 0) // Connected to constructor 

} 

defined class MyTest 

scala> val x = new MyTest(10) 
x: MyTest = [email protected] 

scala> val y = new MyTest(-10) 
java.lang.IllegalArgumentException: requirement failed 
     at scala.Predef$.require(Predef.scala:133) 
+3

Cela ne _return_. Mais il semble que lancer une exception correspond mieux à sa situation. –

4

Un constructeur doit toujours soit terminer complètement, soit abandonner (lancer une exception). Tout le reste laisse votre objet "à moitié construit" et donc impossible à raisonner.

Si dans votre cas, l'objet est valable même si ParseOptions a échoué, alors vous pouvez changer la condition et continuer:

if (parseOptions(args)) { 
    // rest of constructor 
} 
+1

le fait que Scala ne supporte pas le retour du constructeur ne signifie pas qu'il est 'impossible de raisonner'. Remplacez 'if (X) return; ...' par 'if (! X) {...}' et vous serez capable de raisonner autant que vous le souhaitez. –

+0

Huh? N'avez-vous pas vu que renverser le 'si' est exactement ce que j'ai suggéré? Ce que j'ai dit qu'un constructeur devrait finir ou annuler en levant une exception. Il ne peut pas revenir en laissant les choses défaites. – IttayD

Questions connexes