Ответ 1
Почему бы не использовать class
и не инициализировать один экземпляр в main
?
case class Field(width: Int, height: Int) {
//...
}
object Main {
def main(args: Array[String]): Unit = {
val field = Field(30, 25)
}
}
Скажем, я пытаюсь написать простую игру Tic-Tac-Toe. Он имеет поле M x N. В игре есть только одно поле, поэтому он, вероятно, должен быть представлен синглом object
. Вот так:
object Field {
val height : Int = 20
val width : Int = 15
...
}
Но я не хочу жестко задавать высоту и ширину, поэтому было бы неплохо, если бы они могли быть переданы объекту во время выполнения, через конструктор или что-то в этом роде. Но object
не может иметь конструкторов.
Ну, я мог бы изменить height
и width
как var
s, а не val
и ввести новый метод
def reconfigure (h:Int, w:Int) = {
height = h
width = w
}
и назовите его в начале игры. Но это тоже не изящно.
Итак, есть ли опрятный способ сделать это - т.е. иметь объект val
, инициализированный со значениями, неизвестными до выполнения?
Почему бы не использовать class
и не инициализировать один экземпляр в main
?
case class Field(width: Int, height: Int) {
//...
}
object Main {
def main(args: Array[String]): Unit = {
val field = Field(30, 25)
}
}
Вы можете использовать ленивые деньги. Это может сделать вещи более сложными, если вам все еще нужно использовать var.
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 ) )
}
Один вариант - ленивый vals:
object Field {
lazy val height = // code to find height
lazy val width = // code to find width
}
Значение val будет инициализировано при первом использовании, поэтому пока вы не будете использовать их, пока не получите всю информацию, необходимую для их инициализации, вы должны быть хорошими.