Почему scala использует отражение для вызова метода на структурном типе?

Если функция принимает структурный тип, она может быть определена как:

def doTheThings(duck: { def walk; def quack }) { duck.quack }

или

type DuckType = { def walk; def quack  }
def doTheThings(duck: DuckType) { duck.quack }

Тогда, вы можете использовать эту функцию следующим образом:

class Dog {
    def walk { println("Dog walk") }
    def quack { println("Dog quacks") }
}

def main(args: Array[String]) {
    doTheThings(new Dog);
}

Если вы декомпилируете (в Java) классы, сгенерированные scalac для моего примера, вы увидите, что аргумент doTheThings имеет тип Object и реализация использует отражение для вызова методов на аргументе (i. e. duck.quack)

Мой вопрос в том, почему именно отражение? Разве нельзя просто использовать anonymous и invokevirtual вместо reflection?

Вот способ перевода (реализации) вызовов структурных типов для моего примера (синтаксис Java, но суть в байткоде):

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();}
    });
  }
}
16
задан Op De Cirkel 16 December 2011 в 19:55
поделиться