2010-08-23 9 views
6

Piszę konstruktora dla mojej "głównej" klasy. Pierwszą rzeczą, którą robi, jest wywołanie metody użycia commons-cli do parsowania wiersza poleceń. Jeśli metoda parseOptions zwróci wartość false, wystąpi błąd i konstruktor powinien zakończyć działanie.Wcześniejszy powrót z konstruktora Scala

Próbowałem pisać następujący kod

if (!parseOptions(args)) return 

ale kompilator narzeka, że ​​mam „powrót instrukcji definicji metody zewnątrz”.

Krótki wywoływania System.exit(1) lub odwracanie Boolean (i oddanie całej reszty mojego logiki wewnątrz rachunku if, czy jest jakiś sposób, aby powrócić „wcześnie” od konstruktora?

Przypuszczam, że mam parseOptions metoda wygeneruje IllegalArgumentException i złapać, że w moim Main obiektu.

Dzięki.

+1

Chociaż zgadzam się z innych odpowiedzi, że żaden konstruktor powinien wrócić normalnie, jeżeli nie jest w stanie aby umieścić instancję w stanie, który spełnia niezmienniki klasy, zastanawiam się, dlaczego nie chcesz używać 'if '? –

+0

Jeśli mam kilka warunków, które mogą skutkować wczesnym powrotem, otrzymam kaskadę 'if' na wielu poziomach. – Ralph

+0

Tak? Jeśli jest to logika twojego konstruktora, taka jest logika twojego konstruktora. Zaleca się także * nie *, aby mieć dużo skomplikowanej logiki w swoich konstruktorach. Idealnie po prostu "zanotują" wartości składające się na stan/wartość instancji. –

Odpowiedz

11

jest jakiś sposób, aby powrócić "wcześnie" od konstruktora

Nie, ale w twoim przypadku to brzmi jak zły projektowania, tak.

Jeżeli sposób parseOptions zwraca fałsz, że wystąpił błąd

W tym przypadku, konstruktor powinny rzucać wyjątek nie zwraca normalnie.

+0

Po ponownym przemyśleniu (i wdrożeniu go za pomocą 'IllegalArgumentException'), zgadzam się, że zła analiza linii poleceń zasługuje na wyjątek. – Ralph

12

Dont spróbować zrobić wczesne/przedwczesny powrót, to sprawia, że ​​Twój kod trudniejsze bardziej skomplikowane, ponieważ skutki uboczne w zamian może być h ard do zrozumienia. Zamiast tego użyj wyjątku, aby zasygnalizować, że coś jest nie tak.

Możesz użyć require w konstruktorze. To nie wraca. Wygląda jednak na to, że wyrzucenie wyjątku lepiej pasuje do jego sytuacji.

na przykład:

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

To nie _return_. Wygląda jednak na to, że wyrzucenie wyjątku lepiej pasuje do jego sytuacji. –

4

Konstruktor powinien zawsze albo całkowicie zakończyć, albo przerwać (wyrzucić wyjątek). Wszystko inne pozostawia twój obiekt "w połowie skonstruowanym", a zatem niemożliwym do zrozumienia.

Jeśli w Twoim przypadku, przedmiot jest ważny, nawet jeśli parseOptions niepowodzeniem, wówczas można zmienić stan i dalej:

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

fakt, że Scala nie obsługuje zwrotu z konstruktora, nie oznacza, że ​​jest "niemożliwy do zrozumienia". Zastąp 'if (X) return; ...' z 'if (! X) {...}' i będziesz w stanie rozumować tyle, ile chcesz. –

+0

Huh? czy nie widzisz, że cofnięcie "jeśli" jest dokładnie tym, co zasugerowałem? Co powiedziałem, że konstruktor powinien zakończyć lub wycofać, rzucając wyjątek. Nie może wrócić, pozostawiając rzeczy zniszczone. – IttayD

Powiązane problemy