Se funzione accetta tipo strutturale, può essere definito come:Perché scala usa il reflection per chiamare il metodo sul tipo strutturale?
def doTheThings(duck: { def walk; def quack }) { duck.quack }
o
type DuckType = { def walk; def quack }
def doTheThings(duck: DuckType) { duck.quack }
Quindi, è possibile utilizzare tale funzione nel modo seguente:
class Dog {
def walk { println("Dog walk") }
def quack { println("Dog quacks") }
}
def main(args: Array[String]) {
doTheThings(new Dog);
}
Se si decompila (in Java) le classi generate da scalac per il mio esempio, puoi vedere che l'argomento di doTheThings
è di tipo Object
e l'im la plementazione usa la riflessione per chiamare i metodi sull'argomento (ad es. duck.quack
)
La mia domanda è perché la riflessione? Non è possibile usare solo l'anonimo e invokevirtual invece di riflessione?
Qui è il modo di tradurre (implementare) il tipo strutturale richiede per il mio esempio (sintassi di Java, ma il punto è il bytecode):
class DuckyDogTest {
interface DuckType {
void walk();
void quack();
}
static void doTheThing(DuckType d) {
d.quack();
}
static class Dog {
public void walk() { System.out.println("Dog walk"); }
public void quack() { System.out.println("Dog quack"); }
}
public static void main(String[] args) {
final Dog d = new Dog();
doTheThing(new DuckType() {
public final void walk() { d.walk(); }
public final void quack() { d.quack();}
});
}
}
Non capisco l'ultima frase, puoi, per favore, spiegare? –
@ om-nom-nom 'invokevirtual' non è presente su JVM 1.5 e 1.6, quindi Scala non può fare affidamento su di esso. Scala 2.10 in realtà deprecare JVM 1.5, ma è ancora un po 'di tempo prima che Scala possa sfruttare le cose presenti solo su JVM 1.7. –
@Daniel C. Sobral: Immagino che intendessi "invokedynamic" invece di "invokevirtual" nel tuo ultimo commento –