2010-08-23 1 views
6

Sto scrivendo il costruttore per la mia classe "principale". La prima cosa che fa è chiamare un metodo per usare commons-cli per analizzare la riga di comando. Se il metodo parseOptions restituisce false, si è verificato un errore e il costruttore deve uscire.Ritorno anticipato da un costruttore di Scala

ho provato a scrivere il seguente codice

if (!parseOptions(args)) return 

ma il compilatore si lamenta che ho una "definizione di un metodo di fuori dichiarazione di ritorno".

corto di chiamare System.exit(1) o invertendo la booleana (e mettendo tutto il resto della mia logica all'interno della dichiarazione if, c'è qualche modo per tornare "presto" da un costruttore?

Suppongo che avrei potuto avere il parseOptions metodo di gettare un IllegalArgumentException e cattura che nel mio Main oggetto.

Grazie.

+1

Mentre sono d'accordo con le altre risposte che nessun costruttore dovrebbe restituire normalmente se non era in grado per mettere l'istanza in uno stato che soddisfa gli invarianti della sua classe, mi chiedo perché tu sia contrario all'uso di "if"? –

+0

Se ho diverse condizioni che possono portare a un ritorno anticipato, finirò con una cascata di 'se' molti livelli in profondità. – Ralph

+0

Quindi? Se questa è la logica del tuo costruttore, questa è la logica del tuo costruttore. In genere è anche consigliato * non * di avere un sacco di logica complessa nei costruttori. Idealmente si limitano a "annotare" i valori che comprendono lo stato/valore dell'istanza. –

risposta

11

Esiste un modo per tornare "presto" da un costruttore

No. Ma nel tuo caso suona come una cattiva progettazione, in ogni caso.

Se il metodo parseOptions restituisce false, si è verificato un errore

In questo caso il costruttore dovrebbe lanciare un'eccezione, non restituisce normalmente.

+0

Dopo averlo ripensato (e averlo implementato usando 'IllegalArgumentException'), sono d'accordo che un'analisi errata della riga di comando merita un'eccezione. – Ralph

12

Non provare a fare un ritorno/prematuro presto, questo rende il vostro codice più difficile più complessa, dal momento che gli effetti collaterali di ritorno possono essere h ardire per capire. Usa invece un'eccezione per segnalare che qualcosa non va.

È possibile utilizzare require nel costruttore. Questo non torna. Ma sembra che lanciare un'eccezione si adatti meglio alla sua situazione.

come in:

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

Questo non _return_. Ma sembra che lanciare un'eccezione si adatti meglio alla sua situazione. –

4

Un costruttore deve sempre completare completamente o interrompere (lanciare un'eccezione). Qualsiasi altra cosa lascia il tuo oggetto "a metà costruito" e quindi impossibile ragionare.

Se nel tuo caso, l'oggetto è valida anche se parseOptions fallito, allora si può cambiare la condizione e continua:

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

il fatto che Scala non supporti il ​​ritorno dal costruttore non significa che sia "impossibile ragionare". Sostituisci 'if (X) return; ...' con 'if (! X) {...}' e sarai in grado di ragionare quanto vuoi. –

+0

Eh? non hai visto che invertire il "se" è esattamente quello che ho suggerito? Quello che ho detto che un costruttore dovrebbe finire o roll-back lanciando un'eccezione. Non può tornare lasciando le cose non fatte. – IttayD