如何使用仅在运行时知道的值初始化对象值?

Sap*_*ime 14 scala

假设我正在尝试编写一个简单的Tic-Tac-Toe游戏.它有一个M×N场.游戏只有一个字段,所以它可能应该用单例表示object.像这样:

object Field {
    val height : Int = 20
    val width : Int = 15
    ...
}
Run Code Online (Sandbox Code Playgroud)

但是我不想硬编码高度和宽度,所以如果可以在运行时通过构造函数或其他东西将它们传递给对象会很好.但是objects不能有构造函数.

好吧,我可以改变heightwidth成为vars,而不是vals并引入一种新方法

def reconfigure (h:Int, w:Int) = {
    height = h
    width = w
}
Run Code Online (Sandbox Code Playgroud)

并在游戏开始时调用它.但它也不优雅.

那么,有没有一种巧妙的方法 - 即使用val运行时之前未知的值初始化对象?

mis*_*tor 15

为什么不使用a class并初始化一个实例main

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

object Main {
  def main(args: Array[String]): Unit = {
    val field = Field(30, 25)
  }
}
Run Code Online (Sandbox Code Playgroud)

  • @Saptamus只是因为单例模式被称为设计模式并不意味着它优雅而你应该使用它.我正在使用对象,我不会将它们用于您的用例. (6认同)
  • 使用类肯定是要走的路.@SaptamusPrime不知道为什么你说它不优雅.您描述的情况是OO架构中的标准用例.您试图在不适合的情况下强制使用Object.对象旨在用作类的伴侣,用于保存所有实例的共同内容,例如Java中类的静态部分.这就是为什么他们被称为"伴侣对象". (3认同)
  • 因为它不优雅。必须在 Scala 中引入“对象”是有原因的。否则,人们为什么要使用物体呢? (2认同)

Nei*_*ssy 13

你可以使用懒惰的vals.这可能会使你仍然需要使用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 ) )
}
Run Code Online (Sandbox Code Playgroud)