在调用默认构造函数之前,是否可以验证重载构造函数中的参数?例如。假设我的类有一个默认的构造函数
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))
}
是否有可能以某种方式执行验证?
答案 0 :(得分:4)
Scala中的辅助构造函数必须首先调用另一个构造函数,请参阅Scala Language Reference, Section 5.3.1, p. 74或Scala 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.html或http://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)
}
}