2012-06-13 20 views
7

Tengo un código Scala que usa tipos existenciales que estoy actualizando a 2.10, y noté una advertencia acerca de agregar "import language.existentials" que me hace pensar que debería haber una mejor manera de escribir esta. El código que tengo se reduce a:Reemplazo idiomático para tipos existenciales

class A { 
    private var values = Set.empty[(Class[_], String)] 
    def add(klass: Class[_], id: String) { 
    val key = (klass, id) 
    if (!values(key)) { 
     values += key 
     // More logic below.. 
    } 
    } 

me sale esta advertencia:

[warn] test.scala:4 inferred existential type (Class[_$2], String) forSome { type _$2 }, which cannot be expressed by wildcards, should be enabled 
[warn] by making the implicit value language.existentials visible. 
[warn] This can be achieved by adding the import clause 'import language.existentials' 
[warn] or by setting the compiler option -language:existentials. 
[warn] See the Scala docs for value scala.language.existentials for a discussion 
[warn] why the feature should be explicitly enabled. 
[warn]  val key = (klass, id) 

¿Hay alguna manera de reescribir mi código no genera esta advertencia (o necesitan la importación), o es que la forma más idiomática de expresarlo? Nunca pregunto sobre el parámetro tipo de Clase en ningún lugar del código.

Respuesta

8

La advertencia es sobre la inferencia del tipo existencial, que generalmente no es deseable. Agregue la declaración de importación o explíquela:

val key: (Class[_], String) = (klass, id) 
+0

lo siento, no entiendo el punto. ¿Por qué el tipo inferido es peligroso o indeseable? El parámetro en Clase no importa, casi nunca lo hace cuando tienes que lidiar con las clases y la reflexión (ya que se borra y, por lo tanto, no tiene valor en el momento en que te obligan a inspeccionar o usar la información de la clase). ¿Por qué se nos obligará a escribir una declaración de tipo superfluo para algo tan claro y simple como la clave en este caso? * Hay * una declaración de tipo una línea arriba, entonces, ¿dónde está el problema? – Ichthyo

+0

déjeme aclarar: soy consciente de que puede compilar cosas muy complicadas y confusas con la sintaxis completa para tipos existenciales. Pero en este caso aquí, ¿dónde está el problema o el peligro? 'La clase [_]' parece adecuada – Ichthyo

+0

@Iththyo que podría ser cierto para Class, pero una lista existencial no es tan útil, por ejemplo. El parámetro de tipo en Class es en su mayoría inútil, por lo que existencial con él no es un gran problema. –

4

Si proporciona un parámetro de tipo para el método de agregar, la advertencia desaparece. Esto no afecta lo que se puede almacenar en los valores de var. No tengo una buena respuesta sobre por qué, pero es una solución. Con suerte, alguien más capaz también responderá con una explicación.

class A { 
    private var values = Set.empty[(Class[_], String)] 

    def add[T](klass: Class[T], id: String) { 
     val key = (klass, id) 
     if (!values(key)) { 
     values += key 
     // More logic below.. 
     } 
    } 
    } 
Cuestiones relacionadas