Pregunta

Tengo el siguiente código Java simple:

package testj;
import java.util.*;

public class Query<T> {

    private static List<Object> l = Arrays.<Object>asList(1, "Hello", 3.0);

    private final Class<? extends T> clazz;

    public static Query<Object> newQuery() { return new Query<Object>(Object.class); }

    public Query(Class<? extends T> clazz) { this.clazz = clazz; }

    public <S extends T> Query<S> refine(Class<? extends S> clazz) {
        return new Query<S>(clazz);
    }

    public List<T> run() {
        List<T> r = new LinkedList<T>();
        for (Object o : l) {
            if (clazz.isInstance(o)) r.add(clazz.cast(o));
        }
        return r;
    }
}

Puedo llamar a esto desde Java de la siguiente manera:

Query<String> sq = Query.newQuery().refine(String.class); //NOTE NO <String>

Pero si intento hacer lo mismo desde Scala:

val sq = Query.newQuery().refine(classOf[String])

Obtuve el siguiente error:

Error: escriba desajuste
Encontrado: Lang.This.Class [Scala.This.Predef.String
Requerido: lang.this.class [? 0] antes de {type? 0 <:? }
val sq = query.newQuery (). Refine (classOf [String])

¡Esto solo se soluciona por la inserción del parámetro de tipo correcto!

val sq = Query.newQuery().refine[String](classOf[String])

¿Por qué Scala no puede inferir esto de mi argumento? Nota que estoy usando Scala 2.7

¿Fue útil?

Solución

La inferencia funciona contra Scala 2.8.0.beta1.

Para versiones anteriores, funciona si cambia:

public <S extends T> Query<S> refine(Class<? extends S> clazz)

a:

public <S extends T> Query<S> refine(Class<S> clazz)

scalac -print sugiere que la interpretación de las firmas de Java no ha cambiado en las versiones de Scala. Entonces, la diferencia está probablemente en el Typer/Inferencer en sí.

Scala 2.7.5

Original

def refine[S >: _root_.scala.Nothing <: T](clazz: Class[_$1] forSome {
  type _$1 >: Nothing <: S
}): Query[S] = _;

Modificado

def refine[S >: _root_.scala.Nothing <: T](clazz: Class[S]): Query[S] = _;

Scala 2.8.0.beta1

Original

def refine[S >: scala.Nothing <: T](clazz: Class[_$1] forSome {
  type _$1 >: Nothing <: S
} = _): Query[S] = _;

Modificado

def refine[S >: scala.Nothing <: T](clazz: Class[S] = _): Query[S] = _;
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top