Ran in dieses seltsame Verhalten, wenn obere Grenze in der Implementierung geändert, aber vergessen, es in der Schnittstelle zu ändern. Ich denke, letzte Anweisung sollte nicht kompilieren, aber es tut und gibt unerwartetes Ergebnis zurück.Seltsames Verhalten der Typrückschluss in Funktion mit Obergrenze
trait SuperBase
trait Base extends SuperBase
class SuperBaseImpl extends SuperBase
trait Service {
def doWork[T <: Base : Manifest](body: T => Unit): String
def print[T <: Base : Manifest]: String
}
object ServiceImpl extends Service {
override def doWork[T <: SuperBase : Manifest](body: T => Unit): String =
print[T]
def print[T <: SuperBase : Manifest]: String =
manifest[T].runtimeClass.toString
}
val s: Service = ServiceImpl
// does not compile as expected
// s.print[SuperBaseImpl]
// returns "interface Base"
s.doWork { x: SuperBaseImpl =>() }
bearbeiten
Wie @ som-snytt mit -Xprint:typer
Option erwähnt können wir sehen, welche Compiler folgert tatsächlich:
s.doWork[Base with SuperBaseImpl]
Dies erklärt, warum wir "Schnittstelle Base" bekommen. Aber ich verstehe immer noch nicht ganz, wie und warum Inferenz in diesem Fall funktioniert.
Danke, aber ich denke, es ist einfacher, 'T' explizit zu definieren:' s.doWork [SuperBaseImpl] {x =>()} '. –