Chciałbym sprawdzić argumenty konstruktora i odmówić konstruowania rzucania IllegalArgumentException
w przypadku, gdy zestaw argumentów jest nieprawidłowy (wartości nie mieszczą się w oczekiwanych ograniczeniach). Jak to zapisać w Scali?Jak sprawdzić argumenty konstruktora i wyrzucić wyjątek lub dokonać asercji w domyślnym konstruktorze w Scali?
Odpowiedz
W Scali całe ciało klasy jest podstawowym konstruktorem, więc można tam dodać swoją logikę walidacji.
scala> class Foo(val i: Int) {
| if(i < 0)
| throw new IllegalArgumentException("the number must be non-negative.")
| }
defined class Foo
scala> new Foo(3)
res106: Foo = [email protected]
scala> new Foo(-3)
java.lang.IllegalArgumentException: the number must be positive.
Scala dostarcza sposobu użytkową require
, który pozwala pisać to samo bardziej zwięzły sposób następujący:
class Foo(val i: Int) {
require(i >= 0, "the number must be non-negative.")
}
Lepszym rozwiązaniem może być stworzenie metody fabryki, który daje scalaz.Validation[String, Foo]
zamiast rzucania wyjątek. (Uwaga: wymaga Scalaz)
scala> :paste
// Entering paste mode (ctrl-D to finish)
class Foo private(val i: Int)
object Foo {
def apply(i: Int) = {
if(i < 0)
failure("number must be non-negative.")
else
success(new Foo(i))
}
}
// Exiting paste mode, now interpreting.
defined class Foo
defined module Foo
scala> Foo(3)
res108: scalaz.Validation[java.lang.String,Foo] = Success([email protected])
scala> Foo(-3)
res109: scalaz.Validation[java.lang.String,Foo] = Failure(number must be non-negative.)
scala> class Foo(arg: Int) {
| require (arg == 0)
| }
defined class Foo
scala> new Foo(0)
res24: Foo = [email protected]
scala> new Foo(1)
java.lang.IllegalArgumentException: requirement failed
Nice! Jaka doskonała odpowiedź na to pytanie. Czy możesz trochę rozwinąć (lub link do opracowania) na temat szczegółów działania 'require'? –
Oto, w jaki sposób 'require' działa, @ dan-burton ;-) http://pastebin.com/rJQfTCX9 Po prostu wyrzuca' new IllegalArgumentException ("wymaganie nie powiodło się") 'jeśli argument jest fałszywy. Cała idea używania 'require' zamiast po prostu wyrzucać wyjątek, to sprawić, że twój kod będzie ładniejszy i lepiej nadaje się do analizy statycznej (co wydaje się jeszcze nie zaimplementowane). – Ivan
+1 miłe wyjaśnienie –
nie wiedział o trybie wklejania, +1 :) – wbarksdale
Oznacza to, że Scala jest świetnym językiem – Pooya