scala 如何使用仅在运行时已知的值初始化对象 val?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/8782448/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How do I initialize object vals with values known only at runtime?
提问by Saptamus Prime
Let's say I'm trying to write a simple Tic-Tac-Toe game. It has an M x N field. The game has only one field, so it probably should be represented with a singleton object. Like this:
假设我正在尝试编写一个简单的井字游戏。它有一个 M x N 字段。游戏只有一个字段,所以它可能应该用单例来表示object。像这样:
object Field {
val height : Int = 20
val width : Int = 15
...
}
But I don't want to hardcode the height and width, so it would be nice if those could be passed to the object at runtime, via a constructor or something. But objects cannot have constructors.
但我不想对高度和宽度进行硬编码,所以如果它们可以在运行时通过构造函数或其他东西传递给对象,那就太好了。但是objects 不能有构造函数。
Well, I could change heightand widthto be vars, and not vals and introduce a new method
好吧,我可以改变height并width成为vars,而不是vals 并引入一种新方法
def reconfigure (h:Int, w:Int) = {
height = h
width = w
}
and call it at the begining of the game. But it's not elegant as well.
并在游戏开始时调用它。但它也不优雅。
So, is there a neat way of doing this - i.e. having object vals initialized with values not known before runtime?
那么,是否有一种巧妙的方法可以做到这一点 - 即使用val运行时之前未知的值初始化对象?
回答by missingfaktor
Why not use a classand initialize one instance in main?
为什么不使用 aclass并在 中初始化一个实例main?
case class Field(width: Int, height: Int) {
//...
}
object Main {
def main(args: Array[String]): Unit = {
val field = Field(30, 25)
}
}
回答by Neil Essy
You could employ the use of lazy vals. This may make things more complex any you still need to use a var.
您可以使用惰性值。这可能会使事情变得更加复杂,因为您仍然需要使用 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 ) )
}
回答by Paul Butcher
One option is lazy vals:
一种选择是惰性值:
object Field {
lazy val height = // code to find height
lazy val width = // code to find width
}
The val will be initialised the first time it's used, so as long as you don't use them until you have all the information you need to initialise them, you should be good.
val 将在第一次使用时初始化,因此只要您在获得初始化它们所需的所有信息之前不使用它们,就应该很好。

