Skala -Typ -Inferenzversagen auf “? erweitert “im Java -Code
-
21-09-2019 - |
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
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] = _;