Scala:验证重载构造函数中的参数

时间:2014-06-30 10:25:41

标签: scala

在调用默认构造函数之前,是否可以验证重载构造函数中的参数?例如。假设我的类有一个默认的构造函数

Clazz(foo: String, bar: String)

我想提供另一个构造函数

def this(fooBar: String) {
    //validate if fooBar is of form FOO-BAR, if not, throw some custom exception, else invoke
    this(fooBar.split("-")(0), fooBar.split("-")(1))
}

是否有可能以某种方式执行验证?

1 个答案:

答案 0 :(得分:4)

Scala中的辅助构造函数必须首先调用另一个构造函数,请参阅Scala Language Reference, Section 5.3.1, p. 74Scala constructor overload?因此,无法以建议的方式验证参数。

另见Why can auxiliary constructors in Scala only consist of a single call to another constructor? Odersky,Spoon和Venners的“Scala编程”一书中有关于此主题的以下内容(第6.7节,第147页):

  

如果你熟悉Java,你可能想知道为什么Scala的规则   构造函数比Java更具限制性。在Java中,a   构造函数必须调用同一个类的另一个构造函数,   或者直接调用超类的构造函数,作为它的第一个   行动。在Scala类中,只有主构造函数可以调用a   超类构造函数。 Scala中增加的限制实际上是一个   设计权衡需要支付以换取更大的利益   与Java相比,Scala构造函数的简洁性和简洁性。   超类和构造函数调用的细节和   继承交互将在第10章中解释。

作为您问题的解决方案,您可能需要考虑工厂对象,例如http://fupeg.blogspot.in/2008/11/scala-constructors.htmlhttp://alvinalexander.com/scala/factory-pattern-in-scala-design-patterns这会导致类似以下内容(可能会进行更复杂的验证) :

case class Clazz(foo : String, bar : String)

case class FooBarException(msg: String) extends RuntimeException(msg)

object Clazz {
 def apply(fooBar : String) : Clazz =
     if (fooBar.count(_ == '-') == 1)   
       new Clazz(fooBar.split("-")(0), fooBar.split("-")(1))
     else
       throw new FooBarException("not valid: " + fooBar)
}

object Test extends App {
  val c1 = Clazz("foo", "bar")
  println(c1)
  val c2 = Clazz("foo-bar")
  println(c2)
  try {
    val c3 = Clazz("will throw error")
  } catch {
    case FooBarException(msg) => println(msg)
  }
}