简体   繁体   中英

How do I declare a constructor for an 'object' class type in Scala? I.e., a one time operation for the singleton

I know that objects are treated pretty much like singletons in scala. However, I have been unable to find an elegant way to specify default behavior on initial instantiation. I can accomplish this by just putting code into the body of the object declaration but this seems overly hacky. Using an apply doesn't really work because it can be called multiple times and doesn't really make sense for this use case.

Any ideas on how to do this?

Classes and objects both run the code in their body upon instantiation, by design. Why is this "hacky"? It's how the language is supposed to work. If you like extra braces, you can always use them (and they'll keep local variables from being preserved and world-viewable).

object Initialized {
  // Initalization block
  {
    val someStrings = List("A","Be","Sea")
    someStrings.filter(_.contains('e')).foreach(s => println("Contains e: " + s))
  }

  def doSomething { println("I was initialized before you saw this.") }
}

scala> Initialized.doSomething
Contains e: Be
Contains e: Sea
I was initialized before you saw this.

scala> Initialized.someStrings
<console>:9: error: value someStrings is not a member of object Initialized
       Initialized.someStrings

Rex has it right, I just wanted to point out a pattern I use a lot, that saves you from having to use vars, while avoiding namespace pollution by intermediate values.

object Foo {
  val somethingFooNeeds = {
    val intermediate = expensiveCalculation
    val something = transform(intermediate)
    something
  }
}

If it makes you feel better, you can create some class with protected constructor and object will create singleton of this class:

sealed class MyClass protected (val a: String, b: Int) {
  def doStuff = a + b
}

object MyObject extends MyClass("Hello", b = 1)

Also notice, that sealed stops other classes and objects to extend MyClass and protected will not allow creation of other MyClass instances.

But I personally don't see any problems with some code in the body of the object. You can also create some method like init and just call it:

object MyObject {
  init()

  def init() {
    ...
  }
}

对象和类声明的主体是默认构造函数,放在那里的任何代码都将在第一次引用时执行,因此这正是执行它的方法。

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM