15 Stimmen

Wie initialisiere ich Objektwerte mit nur zur Laufzeit bekannten Werten?

Sagen wir, ich versuche, ein einfaches Tic-Tac-Toe-Spiel zu schreiben. Es hat ein M x N-Feld. Das Spiel hat nur ein Feld, also sollte es wahrscheinlich mit einem singleton object dargestellt werden. So:

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

Aber ich möchte die Höhe und Breite nicht fest codieren, daher wäre es schön, wenn diese zur Laufzeit über einen Konstruktor oder etwas Ähnliches an das Objekt übergeben werden könnten. Aber objects können keine Konstruktoren haben.

Nun könnte ich height und width ändern, damit sie vars und nicht vals sind, und eine neue Methode einführen

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

und sie am Anfang des Spiels aufrufen. Aber elegant ist das auch nicht.

Gibt es also eine elegante Möglichkeit, dies zu tun - also Objekt vals mit Werten initialisieren, die vor der Laufzeit nicht bekannt sind?

14voto

Neil Essy Punkte 3597

Sie könnten die Verwendung von lazy vals nutzen. Dies kann die Dinge komplizierter machen und Sie müssen trotzdem eine Var verwenden.

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 ) )
}

14voto

missingfaktor Punkte 88801

Warum nicht eine Klasse verwenden und eine Instanz in main initialisieren?

case class Feld(breite: Int, höhe: Int) {
  //...
}

object Haupt {
  def main(args: Array[String]): Unit = {
    val feld = Feld(30, 25)
  }
}

3voto

Paul Butcher Punkte 10472

Eine Option sind lazy vals:

object Field {
  lazy val height = // Code, um die Höhe zu finden
  lazy val width = // Code, um die Breite zu finden
}

Das val wird beim ersten Gebrauch initialisiert, also solange Sie sie nicht verwenden, bis Sie alle Informationen haben, die Sie benötigen, um sie zu initialisieren, sollten Sie gut sein.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X