我可以在Scala中定义“方法 - 私有”字段吗?

时间:2010-12-09 16:55:44

标签: scala initialization private access-modifiers

鉴于这种情况:

object ResourceManager {

  private var inited = false

  def init(config: Config) {
    if (inited)
      throw new IllegalStateException
    // do initialization
    inited = true
  }

}

有什么方法可以让inited以某种方式“私有的init()”,这样我可以确定这个类中没有其他方法能够设置inited = false

4 个答案:

答案 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的值,初始化就会运行......