2012-02-07 4 views
35

私はコンストラクタの引数をチェックし、引数のセットが有効でない場合(値が期待される制約に収まらない場合)、IllegalArgumentExceptionをスローするのを拒否したいと思います。これをScalaでコーディングするには?コンストラクタの引数をチェックし、例外をスローするか、またはスキャラのデフォルトのコンストラクタでアサーションを作成する方法はありますか?

答えて

75

Scalaでは、クラス全体が主なコンストラクタであるため、そこで検証ロジックを追加できます。

class Foo(val i: Int) { 
    require(i >= 0, "the number must be non-negative.") 
} 

より良いアプローチを投げるのscalaz.Validation[String, Foo]を代わりに与えファクトリメソッドを提供するために、次のようになります。

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は次のようにあなたがより簡潔同じ事を書き込むことができますユーティリティメソッドrequireを提供します例外。 (注: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.) 
+2

+1良い説明 –

+4

は貼り付けモードについて知りませんでした。+1: – wbarksdale

+0

これは、Scalaが偉大な言語であることを意味します。 – Pooya

15
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 
+1

ニース!質問に対する完全な答え。 'require'がどのように機能するかの詳細について少し詳しく説明できますか? –

+1

これは、 'require'作業を行う方法です。@ dan-burton ;-) http://pastebin.com/rJQfTCX9引数がfalseの場合、' new IllegalArgumentException( "requirement failed") 'をスローします。例外を自分自身で投げるのではなく、 'require'を使う考えは、あなたのコードをよりきれいにし、静的解析(これはまだ実装されていないようです)に適したものにすることです。 – Ivan

関連する問題