web-dev-qa-db-fra.com

Comment vérifier les arguments du constructeur et lever une exception ou faire une assertion dans un constructeur par défaut dans Scala?

Je voudrais vérifier les arguments du constructeur et refuser de construire en lançant IllegalArgumentException au cas où l'ensemble d'arguments n'est pas valide (les valeurs ne correspondent pas aux contraintes attendues). Comment coder cela dans Scala?

43
Ivan

Dans Scala, le corps entier de la classe est votre constructeur principal, vous pouvez donc y ajouter votre logique de validation.

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.

Scala fournit une méthode utilitaire require qui vous permet d'écrire la même chose de manière plus concise comme suit:

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

Une meilleure approche pourrait être de fournir une méthode d'usine qui donne un scalaz.Validation[String, Foo] au lieu de lever une exception. (Remarque: nécessite 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.)
86
missingfaktor
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
18
Luigi Plinge