2011-07-29 28 views
10

Puede que tenga un problema tonto aquí ... Parece que no puedo entender cómo hacer un constructor sin parámetros en Scala. Sé que puedo escribir todo en el cuerpo de la clase (especialmente porque es el único constructor que necesito), pero no me siento bien.Constructor de Scala sin parámetros

Lo que tengo:

class Foo { 
     //some init code 

     //... 
    } 

Lo que me gustaría (pero no funciona como quiera que llame a otro constructor primero):

class Foo { 
     // The only constructor 
     def this() = { 
      //some init code 
     } 

     //... 
    } 

Respuesta

16

Todas las clases en Scala tienen una constructor primario y opcionalmente algunos constructores auxiliares (que deben diferir al constructor primario u otro constructor auxiliar).

El problema en su caso es que en ambos casos ha definido que el constructor principal no toma argumentos, y luego en el segundo caso intenta definir un constructor auxiliar con la misma firma. Esto no funciona, por la misma razón que lo siguiente no se compilará:

// Primary constructor takes a String 
class Foo(s: String) { 
    // Auxiliary constructor also takes a String?? (compile error) 
    def this(a: String) { 
     this(a) 
    } 
} 

Esto no es nada que ver con el hecho de que el constructor es sin argumentos; las siguientes compilaciones por ejemplo:

class Foo(s: String) { 
    // alternative no-arg constructor (with different signature from primary) 
    def this() { 
     this("Default value from auxiliary constructor") 
    } 
} 

En particular, en el segundo ejemplo, el comentario "el único constructor" es mal. Los constructores auxiliares son siempre secundarios al constructor primario, y nunca pueden ser el único constructor.

FWIW, el primer ejemplo es la única opción que tiene abierta, pero me parece bien. Si acaba de comenzar a utilizar Scala, estoy seguro de que comenzará a sentirse bien lo suficientemente pronto, y es importante evitar las formas Java de hacer las cosas cuando hay más alternativas idiomáticas.

+2

Los constructores auxiliares también pueden diferir a otros constructores auxiliares definidos anteriormente. –

+0

@ jean-phillipe: Gracias, tienes razón. Me di cuenta de que no era exacto en el ámbito más amplio yo mismo; puesto corregido ahora –

+0

Gracias, algo me molestó sobre los constructores de Scala desde el principio, pero nunca me estorbó demasiado ... todo está claro ahora. – HairyFotr

4

Bueno, poner el código init en el cuerpo de la clase es la única forma de tener un constructor sin parámetros. Supongo que si quieres puedes hacer algo como:

class Foo { 

    private def init { 
    //init code here 
    } 

    init() 
} 

eso es lo más cerca que vas a conseguir.

10

Por lo que vale, puede introducir un alcance adicional para "marcar" el código de inicio.

class Foo { 
    { 
     // init code here 
    } 
} 
+0

Me gusta mucho esto. ¡Viniendo de Java, tener el código de constructor predeterminado en el cuerpo de la clase simplemente se siente demasiado desordenado! –

+0

Gracias por las lindas palabras, pero si fuera tú no me acostumbraría.He estado en el paisaje de Scala durante los últimos 7 años y no he visto este patrón en ningún lugar, ni siquiera una vez. ;) – agilesteel

4

El código init es el cuerpo del método. Pero puede hacer esto, si le molesta demasiado:

class Foo { 
     locally { 
      //some init code 
     } 
} 
+0

¿Qué es 'localmente' en este contexto? ¿Es una palabra reservada? ¿Se puede hacer referencia en cualquier lugar? –

+0

@user Es un método en línea definido en 'Predef', que devuelve el valor del bloque. Se puede hacer referencia en cualquier lugar. –

Cuestiones relacionadas