2012-01-05 15 views
11

Trong các phiên bản Scala trước 2.9.0, việc triển khai hàm cụ thể trong các đặc điểm được biên dịch như các phương thức thông thường. Từ 2.9.x trở đi, chúng được biên dịch thành các phương thức cầu nối. Tôi đang cố gắng tìm ra lý do đằng sau sự thay đổi này, bởi vì nó ảnh hưởng tiêu cực đến người dùng của nhiều khung công tác Java phổ biến như Spring và Jersey.Tại sao việc triển khai hàm cụ thể trong các đặc điểm được biên dịch thành các phương thức cầu trong Scala 2.9.x nhưng không phải trong 2.8.x?

xem xét mã Scala sau:

trait Speaks { 
    def speak() = { 
    println("woof") 
    } 
} 

class Dog extends Speaks { 
    def wag() = { 
    println("wag wag") 
    } 
} 

Khi lớp Dog được biên soạn với phiên bản 2.8.1 scalac và dịch ngược với javap, kết quả cho "nói chuyện" và chức năng "wag" trông như thế này:

public void speak(); 
    flags: ACC_PUBLIC 
    Code: 
     stack=1, locals=1, args_size=1 
     0: aload_0  
     1: invokestatic #11     // Method Speaks$class.speak:(LSpeaks;)V 
     4: return   
     LineNumberTable: 
     line 7: 0 

public void wag(); 
    flags: ACC_PUBLIC 
    Code: 
     stack=2, locals=1, args_size=1 
     0: getstatic  #18     // Field scala/Predef$.MODULE$:Lscala/Predef$; 
     3: ldc   #20     // String wag wag 
     5: invokevirtual #24     // Method scala/Predef$.println:(Ljava/lang/Object;)V 
     8: return   
     LineNumberTable: 
     line 9: 0 

Khi Chó được biên soạn với phiên bản 2.9.1 scalac và một lần nữa decompiled, hai chức năng tương tự như sau:

public void speak(); 
    flags: ACC_PUBLIC, ACC_BRIDGE 
    Code: 
    stack=1, locals=1, args_size=1 
     0: aload_0  
     1: invokestatic #11     // Method Speaks$class.speak:(LSpeaks;)V 
     4: return   
    LineNumberTable: 
     line 7: 0 

public void wag(); 
    flags: ACC_PUBLIC 
    Code: 
    stack=2, locals=1, args_size=1 
     0: getstatic  #18     // Field scala/Predef$.MODULE$:Lscala/Predef$; 
     3: ldc   #20     // String wag wag 
     5: invokevirtual #24     // Method scala/Predef$.println:(Ljava/lang/Object;)V 
     8: return   
    LineNumberTable: 
     line 9: 0 

Phần có vấn đề là việc thêm cờ ACC_BRIDGE vào hàm speak(). Các khung như Jersey và Spring cố ý không nhận ra các phương thức cầu trong nhiều trường hợp như giải pháp cho các vấn đề khác.

Vì vậy, bất kỳ ai cũng có thể giải thích hoặc chỉ ra giải thích tốt về lý do thay đổi này được thực hiện trong Scala 2.9.x?

Làm theo dõi, có cách nào để vô hiệu hóa hành vi này thông qua chú thích hàm, cờ trình biên dịch, v.v. không?

+3

Câu hỏi thú vị nhưng, giống như rất nhiều những câu hỏi thiết kế, nó có thể được tốt hơn [đầu tiên] hỏi về ML (và sau đó cấy/tập trung ở đây). Ví dụ. câu hỏi SO cuối cùng có thể là "Làm thế nào tôi có thể nhận mùa xuân để nhận ra ..." –

Trả lời

Các vấn đề liên quan