Как инициализировать значения объекта со значениями, известными только во время выполнения? - PullRequest
14 голосов
/ 09 января 2012

Допустим, я пытаюсь написать простую игру в крестики-нолики. У него есть поле M x N. В игре только одно поле, поэтому, вероятно, оно должно быть представлено синглтоном object. Как это:

object Field {
    val height : Int = 20
    val width : Int = 15
    ...
}

Но я не хочу жестко задавать высоту и ширину, поэтому было бы хорошо, если бы они могли быть переданы объекту во время выполнения, через конструктор или что-то еще. Но object s не может иметь конструкторов.

Ну, я мог бы изменить height и width на var с, а не val с и ввести новый метод

def reconfigure (h:Int, w:Int) = {
    height = h
    width = w
}

и позвоните в начале игры. Но это не элегантно.

Итак, есть ли изящный способ сделать это - т.е. инициализировать объект val значениями, неизвестными до времени выполнения?

Ответы [ 3 ]

15 голосов
/ 09 января 2012

Почему бы не использовать class и инициализировать один экземпляр в main?

case class Field(width: Int, height: Int) {
  //...
}

object Main {
  def main(args: Array[String]): Unit = {
    val field = Field(30, 25)
  }
}
13 голосов
/ 09 января 2012

Вы можете использовать ленивые вальсы. Это может сделать вещи более сложными, если вам все еще нужно использовать переменную.

case class Config( height: Int, width: Int )
object Field {
  val defaultConfig = Config( 20, 15 )
  var config: Option[Config] = None
  def getConfig = config.getOrElse( defaultConfig )
  lazy val height = getConfig.height
  lazy val width = getConfig.width
}
object Main extends App {
  Field.config = Some( Config( 30, 25 ) )
}
3 голосов
/ 09 января 2012

Один из вариантов - lazy vals:

object Field {
  lazy val height = // code to find height
  lazy val width = // code to find width
}

Значение val будет инициализировано при первом использовании, поэтому, если вы не используете их, пока у вас не будет всей информации, необходимой для их инициализации, у вас все будет хорошо.

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