2010-08-23 15 views
6

Escribo el constructor para mi clase "principal". Lo primero que hace es llamar a un método para usar commons-cli para analizar la línea de comando. Si el método parseOptions devuelve falso, se ha producido un error y el constructor debería salir.Regreso temprano de un constructor de Scala

he intentado escribir el siguiente código

if (!parseOptions(args)) return 

pero el compilador se queja de que tengo una "declaración de retorno del método fuera de la definición".

a pedir System.exit(1) o invirtiendo el booleano (y poniendo todo el resto de mi lógica dentro de la instrucción if, ¿hay alguna manera de volver "temprana" de un constructor?

Supongo que podría tener la parseOptions método de lanzar un IllegalArgumentException y coger que en mi objeto Main.

Gracias.

+1

Aunque estoy de acuerdo con las otras respuestas que ningún constructor debe devolver normalmente si no estaba en condiciones para poner la instancia en un estado que satisfaga las invariantes de su clase, me pregunto por qué eres reacio a usar 'if'? –

+0

Si tengo varias condiciones que pueden dar como resultado un retorno anticipado, terminaré con una cascada 'if' de muchos niveles de profundidad. – Ralph

+0

Entonces? Si esa es la lógica de tu constructor, esa es la lógica de tu constructor. En general, se aconseja * no * tener mucha lógica compleja en sus constructores. Idealmente, simplemente "anotan" los valores que comprenden el estado/valor de la instancia. –

Respuesta

11

¿Hay alguna manera de volver "temprana" de un constructor

No. Pero en su caso, suena como un mal diseño, de todos modos.

Si el método devuelve false parseOptions, se ha producido un error

En este caso, el constructor debe lanzar una excepción, no vuelve normalmente.

+0

Después de repensar (y de implementarlo usando 'IllegalArgumentException'), acepto que un análisis de línea de comando incorrecto merece una excepción. – Ralph

12

No intentar realizar un envío/prematuro temprano, esto hace que su código sea más difícil más complejo, ya que los efectos secundarios de la devolución puede ser h ard para entender. En su lugar, use una excepción para indicar que algo está mal.

Puede usar require en el constructor. Esto no regresa Pero parece que lanzar una excepción realmente se ajusta mejor a su situación.

como en:

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

Esto no _return_. Pero parece que lanzar una excepción realmente se ajusta mejor a su situación. –

4

Un constructor siempre debe completarse por completo o cancelar (arrojar una excepción). Cualquier otra cosa deja tu objeto "a medio construir" y por lo tanto es imposible razonar sobre ello.

Si, en su caso, el objeto es válido incluso si parseOptions fallaron, entonces puede cambiar el estado y continúa:

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

el hecho de que Scala no admita devolución del constructor no significa que sea "imposible razonar sobre esto". Reemplaza 'if (X) return; ...' con 'if (! X) {...}' y podrás razonar tanto como desees. –

+0

¿Eh? ¿No viste que invertir el 'si' es exactamente lo que sugerí? Lo que dije es que un constructor debe terminar o retroceder arrojando una excepción. No puede regresar dejando cosas deshechas. – IttayD

Cuestiones relacionadas