2009-04-29 20 views
19

Estoy trabajando para aprender Scala, proveniente de un fondo de C++. Estoy intentando escribir una clase pequeña para una aplicación de seguimiento de tareas Estoy pirateando juntos a ayúdame a aprender cómo codificar Scala.Usar variables de clase como constantes en Scala

Esto parece como si debe ser simple, pero por alguna razón que me está eludiendo:

package com.catenacci.tts 

class Task(val ID:Int, val Description:String) { 
val EmptyID = 0 
val EmptyDescription = "No Description" 

def this() = this(EmptyID,EmptyDescription) 
def this(ID:Int)={ 
    this(ID,EmptyDescription) 
} 
def this(Description:String)={ 
    this(EmptyID,Description) 
} 
} 

Estoy tratando de proporcionar tres constructores: Tarea (Identificación, descripción), de tareas (ID), Tarea (Descripción). En los últimos 2 casos quiero inicializar los valores a valores constantes si uno de los valores no es proporcionado por la persona que llama. Y deseo poder verificar esto fuera del de la clase para fines de pruebas unitarias. Así que pensé que poner dos valores públicos me permitiría verificar desde fuera de la clase para hacer y asegurarme de que mi estado es lo que esperaba.

Sin embargo, por alguna razón este código no se compilará. Me sale el siguiente error:

error: not found: value EmptyID 

y

error: not found: value EmptyDescription 

Entonces, ¿qué me falta? Estoy trabajando en "Programación en Scala" así que si hay una respuesta simple a esta pregunta, por favor dame los números de la página . No me importa leer pero siguiendo el código en la página 60 y página 62, no puedo ver por qué este código está fallando.

Supongo que tiene algo que ver con el hecho de que estos son los métodos de constructor y que posiblemente los dos vals no se hayan inicializado hasta el final de los constructores. Si ese es el caso ¿hay alguna forma de obtener el efecto que estoy buscando?

+1

Vea también SIP 23 o '42.type': http://stackoverflow.com/a/39065260/6309 – VonC

Respuesta

38

Se pueden definir las constantes en un objeto acompañante:

object Task { 
val EmptyID = 0 
val EmptyDescription = "No Description" 
} 

Y después hacer referencia a ellos como Task.EmptyID y Task.EmptyDescription.

Creo que Scala 2.8 es compatible con los valores predeterminados.

8

Ver a Germán para la respuesta. Esto sucede porque un constructor es técnicamente parte del alcance estático. En otras palabras, el constructor no puede acceder a los miembros de la instancia porque la instancia aún no se ha creado. Todos los "miembros de la clase" son en realidad miembros de la instancia, por lo que el código en la pregunta no funciona. La respuesta de Germán corrige esto al mover los dos valores relevantes al objeto complementario, lo que los convierte en miembros estáticos de la clase Task (no realmente, pero se puede pensar de esa manera).

+0

Gracias - es bueno saber por qué esto no funcionó tan bien como saber cómo solucionarlo. –

+0

Sí. Por un tiempo me preguntaba por qué esto no era un problema en Java con el clásico "final estático público", es por la estática. –

1

En "Programación en Scala", consulte la sección 6.7 donde se explica el encadenamiento de llamadas de constructor. El constructor primario se describe como "el único punto de entrada de una clase".

Cuestiones relacionadas