Si función acepta tipo estructural, que se puede definir como:¿Por qué Scala usa la reflexión para llamar al método en tipo estructural?
def doTheThings(duck: { def walk; def quack }) { duck.quack }
o
type DuckType = { def walk; def quack }
def doTheThings(duck: DuckType) { duck.quack }
A continuación, puede utilizar esta función en la siguiente forma:
class Dog {
def walk { println("Dog walk") }
def quack { println("Dog quacks") }
}
def main(args: Array[String]) {
doTheThings(new Dog);
}
Si descompilar (a Java) las clases generadas por scalac para mi ejemplo, puede ver que el argumento de doTheThings
es del tipo Object
y el im La plementación utiliza la reflexión para llamar a métodos en el argumento (es decir duck.quack
)
Mi pregunta es ¿por qué reflexión? ¿No es posible usar anonymous e invokevirtual en lugar de reflection?
Aquí es manera de traducir (implementar) el tipo estructural llama para mi ejemplo (sintaxis de Java, pero el punto es el código de bytes):
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();}
});
}
}
No recibo la última oración, ¿pueden explicarme? –
@ om-nom-nom 'invokevirtual' no está presente en JVM 1.5 y 1.6, por lo que Scala no puede confiar en él. Scala 2.10 realmente depreciará JVM 1.5, pero aún le queda algo de tiempo antes de que Scala pueda aprovechar lo presente solo en JVM 1.7. –
@Daniel C. Sobral: Supongo que querías 'invookedynamic' en lugar de' invokevirtual' en tu último comentario –