Frage

Ich habe den folgenden einfachen Java -Code:

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;
    }
}

Ich kann das von Java wie folgt nennen:

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

Aber wenn ich versuche, dasselbe von Scala zu tun:

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

Ich bekomme den folgenden Fehler:

Fehler: Typ Nichtübereinstimmung eingeben
gefunden: lang.this.class [scala.this.predef.string
Erforderlich: lang.this.class [? 0] Forsome {Typ? 0 <:? }
Val SQ = query.newQuery (). Refine (classof [String])

Dies wird nur durch das Einfügen des richtigen Typ -Parameters festgelegt!

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

Warum kann Scala dies nicht aus meinem Argument schließen? Beachten Sie, dass ich es benutze Scala 2.7

War es hilfreich?

Lösung

Die Inferenz wirkt gegen Scala 2.8.0.beta1.

Für frühere Versionen funktioniert es, wenn Sie sich ändern:

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

zu:

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

scalac -print deutet darauf hin, dass sich die Interpretation der Java -Unterschriften in den Scala -Veröffentlichungen nicht geändert hat. Der Unterschied liegt also wahrscheinlich im Typer/Inferenzer selbst.

Scala 2.7.5

Original

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

Geändert

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] = _;

Geändert

def refine[S >: scala.Nothing <: T](clazz: Class[S] = _): Query[S] = _;
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top