在调用 this() 之前在重载构造函数中执行代码
假设我们有一个这样的类:
import java.net.URL
import xml._
class SearchData(xml: Node) {
def this(url: URL) = this (XML.load(url))
}
并且我们想要在调用 this (XML.load(url))
之前执行一些代码 - 比如说用 try
测试它。人们会期望编写这样的代码会起作用:
class SearchData(xml: Node) {
def this(url: URL) {
try {
this (XML.load(url))
} catch {
case _ => this(<results/>)
}
}
}
但事实并非如此,因为 Scala 要求您在重载构造函数中的第一个语句中调用 this()
,在本例中为 try
成为第一个语句。
那么这个问题的解决方案是什么呢?
Say we have a class like this:
import java.net.URL
import xml._
class SearchData(xml: Node) {
def this(url: URL) = this (XML.load(url))
}
and we want to execute some code prior to calling this (XML.load(url))
- say test it with try
. One would expect that writing something like this would work:
class SearchData(xml: Node) {
def this(url: URL) {
try {
this (XML.load(url))
} catch {
case _ => this(<results/>)
}
}
}
but it won't, because Scala requires that you make the call to this()
the first statement in the overloaded constructor and in this case try
becomes the first statement.
So what would be the solution to this problem?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
更一般地,参数的计算必须在构造函数调用之前进行,因此您可以在那里执行此操作(scala 中的块是一个表达式,但编写一个例程,通常编写在伴生对象中,如果它会太长)。您不能做的是让此代码选择您调用的其他构造函数。但由于所有这些都必须路由到第一个,因此您不会损失太多。此外,您需要调用的另一个构造函数至少有一个参数。如果有多个构造函数,则第一个构造函数通常不应是没有参数的构造函数(请参阅 Scala 问题可选构造函数)
More generally, the evaluation of the arguments has to happen before the constructor call, so you do that there (a block in scala is an expression, but write a routine, typically written in the companion object, if it is going to be too long). What you cannot do is have this code choose which other constructor you call. But as all of them must route to the primary one, you do not lose much. Also, you need the other constructor you call to have at least one argument. If there are several constructors, the primary one should normally not be the one without an argument (see Scala problem optional constructor)
伴生对象中的工厂方法:
不仅简化了设计,而且可以省去
new
关键字。A factory method in companion object:
Not only it simplifies design, but you can spare the
new
keyword.虽然 didierd 的解决方案解决了所声明的问题,并且与此问题有些接近,但当您必须在调用
this
之前执行多个语句时,它仍然无法解决问题。这为所有场景提供了一种通用方法:这里的技巧是
this
提供了执行匿名函数的结果,您可以在该函数的主体中执行任何操作。但这仅在您具有单参数主构造函数时才有效 - 在其他情况下,您将不得不引入基于
Tuple
的解决方法:While didierd's solution solves the declared problem and is somewhat close to this one, it still doesn't solve the problem when you have to execute several statements prior to calling
this
. This one provides a general approach to all scenarios:The trick here is that
this
is fed with result of executing an anonymous function in body of which you are allowed to do anything.But this only works when you have a single-argument main constructor - in other scenarios you will have to introduce a
Tuple
-based workaround: