2012-10-11 25 views
5

Câu hỏi liên quan: Scala closures compared to Java innerclasses -> final VS varKhi đóng Scala, khi nào các biến bắt được bắt đầu tồn tại trên vùng JVM?

Tôi tự hỏi khi nào Scala làm cho các biến được chụp thành một đóng cửa trực tiếp trên đống thay vì ngăn xếp. Tôi đang đọc cuốn sách Scala của Martin Odersky nhưng bây giờ tôi không tìm thấy thông tin này. Ai đó có thể giải thích những gì đằng sau mui xe?

Trả lời

8

Một chức năng ẩn danh (và thực sự, bất kỳ chức năng nào) trong scala thực sự là một đối tượng (một thể hiện của Function*). Khi nó được khởi tạo, việc bắt giữ các vals được thực hiện bằng cách sao chép các vals vào các trường bên trong của đối tượng hàm. Trong phần thân hàm (có nghĩa là, trong phương thức apply của đối tượng hàm) quyền truy cập vào các vals bị bắt được thực hiện bằng cách truy cập các trường này.

Việc nắm bắt các vars là tương tự, ngoại trừ trình biên dịch phải thêm một mức độ bất định: giá trị var được truy cập thông qua một số chủ có thể ẩn ẩn (chỉ đơn giản là đối tượng có trường có thể thay đổi trỏ đến giá trị hiện tại của var) và đây là chủ sở hữu này được sao chép vào đối tượng hàm. Khi viết vào var (hoặc bằng mã cục bộ hoặc bởi đối tượng hàm), nó là trường của chủ sở hữu được viết. Cơ chế này đảm bảo rằng mã cục bộ và mã của hàm thao tác cùng một dữ liệu và cả hai đều nhìn thấy các sửa đổi của nhau.

Vì vậy, câu trả lời là một Vals bắt và một var bắt cả hai luôn sống trên heap (dù là trực tiếp như một lĩnh vực của đối tượng chức năng, hoặc như là một lĩnh vực của một số đối tượng wrapper)

+0

Tôi không thể nhìn thấy bất kỳ trường nào trong các trường này nếu tôi chạy 'javap -p Test $$ anonfun $ 1.class' (một hàm ẩn danh trong đối tượng' Test') - bất kỳ ý tưởng nào tại sao không? –

+0

Thêm tùy chọn riêng tư để xem các trường riêng tư –

+0

-p và -private giống nhau. Tôi đã đăng một ví dụ ở đây: http://pastebin.com/AkaR6zjM không hiển thị các trường riêng tư. –

0

Tôi không biết bên trong trình biên dịch, nhưng dưới đây là cách thực hiện. Đối với mỗi biến cục bộ, trình biên dịch duy trì một cờ được khởi tạo thành false. Bất cứ khi nào biến được sử dụng, trình biên dịch sẽ kiểm tra xem nó có đang được sử dụng bên trong một lớp hay một lớp đóng không chứa khai báo của biến đó hay không; nếu vậy cờ được đặt thành true. Ở cuối phạm vi của biến, nếu cờ vẫn còn sai, biến có thể nằm trên ngăn xếp. Nếu không, nó phải sống trên heap.

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