Si la fonction accepte le type de structure, il peut être défini comme:Pourquoi scala utilise la réflexion pour appeler la méthode sur le type structurel?
def doTheThings(duck: { def walk; def quack }) { duck.quack }
ou
type DuckType = { def walk; def quack }
def doTheThings(duck: DuckType) { duck.quack }
, vous pouvez utiliser cette fonction comme suit:
class Dog {
def walk { println("Dog walk") }
def quack { println("Dog quacks") }
}
def main(args: Array[String]) {
doTheThings(new Dog);
}
Si vous décompiler (à Java) les classes générées par scalac pour mon exemple, vous pouvez voir que l'argument de doTheThings
est de type Object
et l'im La mise en œuvre utilise la réflexion pour appeler les méthodes sur l'argument (c.-à-d. duck.quack
)
Ma question est pourquoi réflexion? N'est-il pas possible d'utiliser anonyme et invokevirtual au lieu de la réflexion?
Voici façon de traduire (mise en œuvre) le type de structure appelle pour mon exemple (syntaxe Java, mais le point est le 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();}
});
}
}
Je ne comprends pas la dernière phrase, pouvez-vous, s'il vous plaît, expliquer? –
@ om-nom-nom 'invokevirtual' n'est pas présent sur JVM 1.5 et 1.6, donc Scala ne peut pas compter dessus. Scala 2.10 va réellement déprécier JVM 1.5, mais il faudra encore du temps avant que Scala ne profite des choses présentes uniquement sur JVM 1.7. –
@Daniel C. Sobral: Je suppose que vous vouliez dire 'invokedynamic' au lieu de' invokevirtual' dans votre dernier commentaire –