鉴于这种情况:
object ResourceManager {
private var inited = false
def init(config: Config) {
if (inited)
throw new IllegalStateException
// do initialization
inited = true
}
}
有什么方法可以让inited
以某种方式“私有的init()”,这样我可以确定这个类中没有其他方法能够设置inited = false
?
答案 0 :(得分:6)
取自In Scala, how would you declare static data inside a function?。不要使用方法而是使用函数对象:
val init = { // or lazy val
var inited = false
(config: Config) => {
if (inited)
throw new IllegalStateException
inited = true
}
}
在初始化外部范围(在val
)或第一次访问(lazy val
)的过程中,执行变量的主体。因此,inited
设置为false
。最后一个表达式是一个匿名函数,然后分配给init
。然后,对init
的每次进一步访问都将执行此匿名函数。
请注意,它不像方法一样完全。即没有参数调用它是完全有效的。它的行为就像一个尾随下划线method _
的方法,这意味着它只会返回匿名函数而不会抱怨。
如果由于某种原因,您确实需要方法行为,可以将其设为private val _init = ...
并从公开def init(config: Config) = _init(config)
调用它。
答案 1 :(得分:5)
下面绝对认为它值得更麻烦,但确实满足规格。否则无法这样做
object ResourceManager {
private object foo {
var inited = false
def doInit(config:Config){
if (inited)
throw new IllegalStateException
// do initialization
inited = true
}
}
def inner(config: Config) {
foo.doInit(config)
}
}
答案 2 :(得分:0)
创建一个只能从false变为true的“trapdoor”对象会更容易:
object ResourceManager {
object inited {
private var done = false
def apply() = done
def set = done = true
}
def init(config: Int) {
if (inited())
throw new IllegalStateException
// do initialization
inited.set
}
}
答案 3 :(得分:0)
如果您只想确保调用init
一次,请执行以下操作:
lazy val inited = {
// do the initialization
true
}
def init = inited
初始化代码只会运行一次,但是多次运行init
,而inited
无法获得另一个值,因为它是val
。唯一的缺点是,只要查询inited
的值,初始化就会运行......