如何在Scala中检查构造函数参数并抛出异常或在默认构造函数中进行断言?

Iva*_*van 42 constructor assert scala exception

我想检查构造函数参数并拒绝构造抛出IllegalArgumentException,以防参数集无效(值不符合预期的约束).如何在Scala中编写代码?

mis*_*tor 86

在Scala中,类的整个主体是您的主要构造函数,因此您可以在那里添加验证逻辑.

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 = Foo@3bfdb2

scala> new Foo(-3)
java.lang.IllegalArgumentException: the number must be positive.
Run Code Online (Sandbox Code Playgroud)

Scala提供了一种实用程序方法require,可以让您更简洁地编写相同的内容,如下所示:

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

更好的方法可能是提供一种工厂方法,scalaz.Validation[String, Foo]而不是抛出异常.(注意:需要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(Foo@114b3d5)

scala> Foo(-3)
res109: scalaz.Validation[java.lang.String,Foo] = Failure(number must be non-negative.)
Run Code Online (Sandbox Code Playgroud)

  • 在构造函数中抛出异常并不理想.每当我需要一个对其任何构造函数参数的域有限制的类型时,我将构造函数设为私有并通过应用约束的工厂强制实例化并抛出(通常通过`require`)或返回`Try [ConstrainedType] `. (5认同)

Lui*_*hys 17

scala> class Foo(arg: Int) {
     |   require (arg == 0)
     | }
defined class Foo

scala> new Foo(0)
res24: Foo = Foo@61ecb73c

scala> new Foo(1)
java.lang.IllegalArgumentException: requirement failed
Run Code Online (Sandbox Code Playgroud)

  • 好的!这个问题的答案多么完美啊。您能否详细说明一下(或链接到详细说明)“require”如何工作的细节? (2认同)