Nếu chức năng chấp nhận kiểu cấu trúc, nó có thể được định nghĩa là:Tại sao scala sử dụng phản xạ để gọi phương thức trên kiểu cấu trúc?
def doTheThings(duck: { def walk; def quack }) { duck.quack }
hoặc
type DuckType = { def walk; def quack }
def doTheThings(duck: DuckType) { duck.quack }
Sau đó, bạn có thể sử dụng chức năng theo cách sau:
class Dog {
def walk { println("Dog walk") }
def quack { println("Dog quacks") }
}
def main(args: Array[String]) {
doTheThings(new Dog);
}
Nếu bạn dịch ngược (đối với Java) các lớp được tạo bởi scalac cho ví dụ của tôi, bạn có thể thấy đối số của doTheThings
là loại Object
và im plementation sử dụng sự phản chiếu để gọi các phương thức trên đối số (tức là duck.quack
)
Câu hỏi của tôi là lý do phản ánh? Không phải là nó chỉ có thể sử dụng vô danh và invokevirtual thay vì phản ánh?
Dưới đây là cách để dịch (thực hiện) các loại cấu trúc gọi ví dụ của tôi (cú pháp Java, nhưng điểm mấu chốt là các 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();}
});
}
}
Tôi không nhận được câu cuối cùng, bạn có thể, vui lòng giải thích? –
@ om-nom-nom 'invokevirtual' không có mặt trên JVM 1.5 và 1.6, vì vậy Scala không thể dựa vào nó. Scala 2.10 sẽ thực sự không dùng JVM 1.5, nhưng vẫn còn một thời gian trước khi Scala có thể tận dụng những thứ chỉ có trên JVM 1.7. –
@Daniel C. Sobral: Tôi đoán bạn có nghĩa là 'invokedynamic' thay vì' invokevirtual' trong bình luận cuối cùng của bạn –