Как мне объявить конструктор для типа класса 'объект' в Scala?То есть одноразовая операция для синглтона - PullRequest
16 голосов
/ 05 марта 2011

Я знаю, что объекты обрабатываются почти как синглтоны в scala.Однако мне не удалось найти элегантный способ указать поведение по умолчанию при первоначальной реализации.Я могу сделать это, просто поместив код в тело объявления объекта, но это кажется чрезмерным.Использование apply действительно не работает, потому что его можно вызывать несколько раз и не имеет смысла для этого варианта использования.

Есть идеи, как это сделать?

Ответы [ 4 ]

38 голосов
/ 05 марта 2011

Классы и объекты запускают код в своем теле после его создания, в соответствии с замыслом.Почему это "хакер"?Это как язык должен работать.Если вам нравятся дополнительные фигурные скобки, вы всегда можете их использовать (и они сохранят локальные переменные от сохранения и просмотра для всего мира).

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
18 голосов
/ 05 марта 2011

Рекс все правильно, я просто хотел указать на шаблон, который я часто использую, который избавляет вас от необходимости использовать переменные, избегая загрязнения пространства имен промежуточными значениями.

object Foo {
  val somethingFooNeeds = {
    val intermediate = expensiveCalculation
    val something = transform(intermediate)
    something
  }
}
12 голосов
/ 05 марта 2011

Если вам от этого легче, вы можете создать класс с защищенным конструктором, а object создаст синглтон этого класса:

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

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

Также обратите внимание, что sealed останавливает другие классы и объектырасширение MyClass и protected не позволит создавать другие MyClass экземпляры.

Но лично я не вижу проблем с некоторым кодом в теле объекта.Вы также можете создать некоторый метод, например init, и просто вызвать его:

object MyObject {
  init()

  def init() {
    ...
  }
}
4 голосов
/ 05 марта 2011

Тело объявлений объекта и класса является конструктором по умолчанию, и любой размещенный там код будет выполняться при первой ссылке, так что это точно способ сделать это.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...