2012-01-08 12 views
14

Digamos que estoy tratando de escribir un juego simple de Tic-Tac-Toe. Tiene un campo M x N. El juego tiene solo un campo, por lo que probablemente debería estar representado con un singleton object. De esta manera:¿Cómo inicializo object vals con valores conocidos solo en runtime?

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

Pero yo no quiero codificar la altura y anchura, por lo que sería bueno que los que podrían ser pasados ​​al objeto en tiempo de ejecución, a través de un constructor o algo así. Pero object s no pueden tener constructores.

Bueno, podría cambiar height y width para ser var s, y no val s e introducir un nuevo método

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

y llamo al comienzo del juego. Pero tampoco es elegante.

Entonces, ¿hay una buena manera de hacerlo, es decir, tener el objeto val inicializado con valores desconocidos antes del tiempo de ejecución?

+0

Parece que cualquier solución va a requerir una 'var' en alguna parte. ¿Consideró que 'Field' es una clase con parámetros de constructor de alto y ancho? –

+0

@KiptonBarros Lo hice. Pero solo necesito una instancia única de esa clase. Así que pensé que sería _ideológicamente_ mejor usar 'objeto'. –

Respuesta

15

por qué no utilizar una instancia de class e inicializar una en main?

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

object Main { 
    def main(args: Array[String]): Unit = { 
    val field = Field(30, 25) 
    } 
} 
+0

Porque no es elegante. 'object's debe ser introducido en Scala por una razón. O bien, ¿por qué las personas usan objetos en absoluto? –

+5

@Saptamus Solo porque el patrón singleton se llama patrón de diseño no significa que sea elegante y debe usarlo. Estoy usando objetos y no los usaría para tu caso de uso. – ziggystar

+3

El uso de la clase definitivamente es un camino por recorrer. @SaptamusPrime No estoy seguro de por qué dices que no es elegante. La situación que describe es un caso de uso estándar en la arquitectura OO. Intentas forzar el uso de Object en una situación en la que no encaja. Los objetos están destinados a ser utilizados como acompañantes para una clase, para mantener las cosas comunes a todas las instancias, como la parte estática de una clase en Java. Es por eso que se les llama "objetos acompañantes". –

5

Una opción es Vals perezosos:

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

El val se inicializará la primera vez que se usa, por lo que, siempre y cuando no los use hasta que tenga toda la información que necesita para inicializar ellos, deberías ser bueno.

+1

, pero eso todavía no proporciona la manera de configurar este campo desde el exterior –

+0

Esta respuesta es basura ... Los objetos se inicializan perezosamente de todos modos – lisak

13

Puede emplear el uso de vals perezoso. Esto puede hacer que las cosas sean más complejas ya que aún necesita usar una 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)) 
} 
+0

Creo que entiendo la idea. ¡Gracias! –

Cuestiones relacionadas