Por que scala usa reflexão para chamar o método no tipo estrutural?
Se a função aceitar o tipo estrutural, poderá ser definida como:
def doTheThings(duck: { def walk; def quack }) { duck.quack }
o
type DuckType = { def walk; def quack }
def doTheThings(duck: DuckType) { duck.quack }
Então, você pode usar essa função da seguinte maneira:
class Dog {
def walk { println("Dog walk") }
def quack { println("Dog quacks") }
}
def main(args: Array[String]) {
doTheThings(new Dog);
}
Se você descompilar (para Java) as classes geradas pelo scalac para o meu exemplo, poderá ver esse argumento dedoTheThings
é do tipoObject
e a implementação usa reflexão para chamar métodos no argumento (ou seja,duck.quack
)
Minha pergunta é por que a reflexão? Não é possível usar apenas anônimo e invokevirtual em vez de reflexão?
Aqui está uma maneira de traduzir (implementar) o tipo estrutural chamapara meu exemplo (Sintaxe Java, mas o ponto é o 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();}
});
}
}