2011-09-03 23 views
7

consideran este código:¿Por qué el Manifiesto no está disponible en el constructor?

class Foo[T : Manifest](val id: String = manifest[T].erasure.getName) 

Básicamente quiero para almacenar un identificador en Foo, que a menudo es sólo el nombre de la clase.

La subclase que no necesita un identificador especial podría fácilmente usar el valor predeterminado.

Pero esto ni siquiera compilar, el mensaje de error es:

error: No Manifest available for T. 

¿Hay otro enfoque que funcionará?

EDIT:

¿Por qué este trabajo si el manifiesto no está disponible hasta el constructor principal?

class Foo[T: Manifest](val name: String) { 
    def this() = this(manifest[T].erasure.getName) 
} 
+0

No es una respuesta, pero tendrá un código mucho más limpio si utiliza 'manifest [T]' en lugar de 'implícitamente [Manife st [T]] '. –

Respuesta

9

Cuando el azúcar sintáctica se retira de ese contexto obligado, que se reescribir como:

class Foo[T] 
    (val id: String = implicitly[Manifest[T]].erasure.getName) 
    (implicit ev$1: Manifest[T]) = ... 

Así que la evidencia manifiesta simplemente no está disponible cuando se determina el valor por defecto de id. Yo en cambio iba a escribir algo como esto:

class Foo[T : Manifest](id0: String = "") { 
    val id = if (id0 != "") id0 else manifest[T].erasure.getName 
} 

En el segundo enfoque (que es una gran solución, por cierto!), Le espera una reescritura similar a:

class Foo[T](val name: String)(implicit x$1: Manifest[T]) { 
    def this()(implicit ev$2: Manifest[T]) = this(manifest[T].erasure.getName) 
} 

Así sí, el manifiesto es disponible antes de la llamada a manifest[T].erasure

+0

¿Pero no crea eso un campo superfluo? – soc

+0

Para evitar el campo superfluo, elimine el modificador 'val' de la definición de' id0'? –

+0

Mhhh ... Creo que acabo de resolverlo agregando un – soc

Cuestiones relacionadas