2011-09-03 9 views
19

El lenguaje Scala requiere que inicialice la variable de instancia antes de usarlo. Sin embargo, Scala no proporciona un valor predeterminado para su variable. En su lugar, usted tiene que configurar su valor de forma manual mediante el subrayado de comodín, que actúa como un valor por defecto, de la siguiente manera¿Por qué el lenguaje Scala requiere que inicialices una variable de instancia en lugar de confiar en un valor predeterminado?

var name:String = _ 

Lo sé, lo sé ... Puedo definir un constructor en la definición de clase, que toma como parámetro de nuestra variable de instancia, por lo Scala no forzar su inicialización como se muestra abajo

class Person(var name:String) 

sin embargo, i necesidad de declarar que en el cuerpo porque i necesidad de utilizar una anotación de Java cuyo ElementType es el campo o método; es decir, solo se puede aplicar a una variable de instancia o método declarado en el cuerpo de nuestra clase.

Pregunta: ¿Por qué el lenguaje Scala requiere que inicialices una variable de instancia, ya sea un valor predeterminado _ o lo que quieras, declarada en el cuerpo de una clase en lugar de confiar en un valor predeterminado?

+2

La preferencia de Martin sería mi suposición :-) Por lo menos es explícita y los 2 caracteres adicionales (4 con espacios) no son terriblemente desalentadores. Parece una tontería que Java (un lenguaje muy * verboso *) permita omitir la tarea. Además, parece engañoso decir que los "argumentos del constructor" (no sé cómo se llaman realmente: - /) no están forzados a inicializarse, lo que es más cierto es cuando el objeto se crea una instancia. –

Respuesta

6

Usted puede aplicar la anotación cuando la especifique como un argumento de constructor. Además, es posible que necesite usar una metaanotación para restringir a qué destino se aplica la anotación que está utilizando; consulte http://www.scala-lang.org/api/2.10.2-RC2/index.html#scala.annotation.meta.package

Sin embargo, su pregunta sobre "confiar en un valor predeterminado" no está clara. La inicialización usando un guión bajo corresponde a asignar el valor de la variable a nulo. ¿En qué otro defecto estás pensando?

+0

Sé que el signo de subrayado se usa para asignar un valor predeterminado. Sin embargo, quiero saber por qué Scala no permite algo como var name: String (sin asignación de subrayado) en su lugar cuando se declara en el cuerpo de la clase. Usted señaló una buena característica de Scala (+1) que yo no sabía. Sin embargo, no satisface mis necesidades porque también necesito un constructor no-arg que se invalida si declaro mis variables de instancia en un constructor declarado en la definición de clase –

+4

El motivo por el que se requiere la asignación es, creo, para que el compilador puede distinguir entre una var abstracta (que se compila a un par de métodos abstractos) y una var concreta, que también requiere que el campo se genere en el archivo de clase. –

4

Scala no tiene ningún problema con "var name: String" en el cuerpo de la clase. ¿Lo intentaste? Sin embargo, no significa lo que quieres que signifique. Es una var abstracta

abstract class A { 
    var name: String 
} 
// some possible uses for abstract vars 
trait B { type T ; var name: T } 
class B1 extends B { type T = Int ; var name: Int = 5 } 
// hey, no storage 
class B2 extends B { type T = String ; def name = "abc" ; def name_=(x: String) =() } 
+0

Si solo declaro var nombre: String; cuando se compila en un archivo .class, el compilador de Scala se quejará: el nombre de la variable no está definido. Así que me gustaría saber, incluso debido a problemas de diseño, por qué Scala no permite usar var name: String en el cuerpo de la clase sin declarar su valor inicial; ya sea un valor predeterminado o lo que sea –

+1

Puede volver a leer mi respuesta, que parece haber ignorado. ¿Estás preguntando por qué existe el "resumen"? Un miembro abstracto no implementado significa que no puede crear una instancia de la clase. Esto es por diseño, como en java. – extempore

18

Si utiliza un código como el siguiente que se está declarando, que el name debe ser abstracta:

class A { 
    var name: String 
} 

supongo que ya lo sabía. Entonces su pregunta es más bien de naturaleza sintáctica. La respuesta es la coherencia con otros posibles candidatos abstractos .

Suponga que quiere hacer algo como esto:

class A { 
    var variable: String = _ // variable has some default value (probably null) 
    val value: String = _ // value cannot have any default values, since it cannot be reassigned later. 
    def method: String = _ // method could return some default value (probably null) 
    type theType = _ // what should the default type be? (Any perhaps?) 
} 

Los últimos tres ejemplos ni siquiera se compilan. Ahora supongamos que usted quiere hacer algo como esto:

class A { 
    var variable: String 
    val value: String 
    def method: String 
    type theType 
} 

Desde mi punto de vista, incluso alguien que apenas se entiende Scala ve solamente declaraciones. No hay forma de malinterpretarlos, porque no hay nada más que declaraciones. La única confusión surge cuando vienes de otro idioma y asumes por un segundo que hay algunos valores predeterminados. Pero esta confusión desaparece tan pronto como ve el primer ejemplo (el que tiene los valores predeterminados). Y, por cierto, su clase tiene que ser parte de una jerarquía abstracta para poder declarar miembros abstractos, por lo que incluso si es nuevo en el idioma, ya obtiene ayuda adicional del compilador.

Espero que esto responda a su pregunta y feliz codificación.

+1

Gracias por su respuesta (+1) –

Cuestiones relacionadas