2013-05-08 32 views
7

Tôi đang chơi đùa với Scala. Và tôi đã tìm thấy 3 điều thú vị (tiêu đề là phần thứ ba).Tại sao trình biên dịch Scala cho .NET bỏ qua ý nghĩa của val?

1 biến cục bộ được khai báo là val không được hiểu là cuối cùng.

class HowAreVarAndValImplementedInScala { 
    var v1 = 123 
    val v2 = 456 

    def method1() = { 
    var v3 = 123 
    val v4 = 456 
    println(v3 + v4) 
    } 
} 

nếu tôi biên dịch mã scala trên vào bytecode và sau đó dịch ngược đó vào java, nó trông như thế này:

public class HowAreVarAndValImplementedInScala 
{ 
    private int v1 = 123; 
    private final int v2 = 456; 

    public int v1() 
    { 
    return this.v1; 
    } 

    public void v1_$eq(int x$1) { this.v1 = x$1; } 

    public int v2() { return this.v2; } 

    public void method1() { 
    int v3 = 123; 
    int v4 = 456; 
    Predef..MODULE$.println(BoxesRunTime.boxToInteger(v3 + v4)); 
    } 
} 

chúng ta có thể thấy v2 là cuối cùng, nhưng không phải là v4, tại sao?

biên dịch 2 scala cho .net thêm ghi đè từ khóa để rất nhiều (nếu không phải tất cả) các phương pháp dụ công

nếu chúng ta biên dịch mã scala hiển thị ở trên vào CIL và sau đó dịch ngược nó vào C#, nó là như thế này:

public class HowAreVarAndValImplementedInScala : ScalaObject 
{ 
    private int v1; 
    private int v2; 

    public override int v1() 
    { 
    return this.v1; 
    } 

    public override void v1_$eq(int x$1) 
    { 
    this.v1 = x$1; 
    } 

    public override int v2() 
    { 
    return this.v2; 
    } 

    public override void method1() 
    { 
    int v3 = 123; 
    int v4 = 456; 
    Predef$.MODULE$.println(v3 + v4); 
    } 

    public HowAreVarAndValImplementedInScala() 
    { 
    this.v1 = 123; 
    this.v2 = 456; 
    } 
} 

tất cả phương pháp công khai (không bao gồm hàm tạo) được đánh dấu là ghi đè, tại sao? là cần thiết?

3 trình biên dịch Scala cho .net thua ý nghĩa của val

trong C# mã trên, chúng ta có thể thấy v2 đó chỉ là một lĩnh vực bình thường, trong khi ở phần java couter, v2 được đánh dấu là cuối cùng, shouldn 't v2 được đánh dấu là chỉ đọc bởi trình biên dịch Scala cho .net? (một lỗi?)

+2

Theo như tôi biết, 'final' không có ý nghĩa thời gian chạy trong các biến cục bộ nhưng chỉ nhấn mạnh rằng * bạn sẽ không thay đổi giá trị *. 'cuối cùng' lĩnh vực trong tương phản ngụ ý ví dụ rằng họ đang khởi tạo sau khi constructor đã được thực hiện. Do đó, tôi giả sử ** nó bị bỏ qua cho 'v4' vì nó không liên quan đến máy tính, trong khi' v2' phải là 'final' trong Java. Tôi không chắc chắn đủ để làm cho câu trả lời này, tuy nhiên. –

+9

3 câu hỏi phải là 3 câu hỏi ... –

+0

@MatthiasMeid có, có vẻ như đúng – CuiPengFei

Trả lời

7

Ở cấp bytecode, cuối cùng không tồn tại đối với các biến cục bộ. Trong thực tế, khái niệm về các biến cục bộ không thực sự tồn tại. Đánh dấu một biến cục bộ là biến cuối cùng là hoàn toàn cho việc kiểm tra thời gian biên dịch. Vì thông tin không có trong classfile, trình giải mã không có cách nào để đoán nó. Đối với hai câu hỏi thứ hai, tôi không quen thuộc với bytecode CIL, nhưng nếu tôi phải đoán tôi muốn nói rằng không có lý do gì để không ghi đè lên, và readonly có thể có ngữ nghĩa khác nhau.

Chỉnh sửa: Sau khi xem qua đặc tả CIL, đây là những gì tôi đã tìm thấy.

Tương đương CIL của cờ final của Java cho các trường là initonly, có vẻ như có cùng ngữ nghĩa. Không rõ tại sao trình biên dịch Scala không phát ra điều này. Có lẽ họ chỉ không nhận được xung quanh nó? Hoặc có lẽ trình biên dịch .net mà bạn đã sử dụng không phản ánh điều này. Nếu bạn muốn xem những gì trình biên dịch thực sự tạo ra, tốt nhất bạn nên xem trực tiếp mã byte.

+0

trong CIL, giống như sau: .field private int32 v1 \t.trường private int32 v2 – CuiPengFei

+0

về ghi đè: giá trị ghi đè là gì? lớp cơ sở không bao gồm bất kỳ thành viên nào trong số các thành viên đó – CuiPengFei

+0

Các trường có rất nhiều hiện diện trong mã byte CIL, như các phần tử siêu dữ liệu '.field'. Và CIL 'initonly' tương đương với' readonly' của C#. – Virtlink

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