Scala cho phép đóng cửa nhưQuản lý bộ nhớ của bao đóng trong công việc Scala như thế nào?
def newCounter = {
var a=0
() => {a+=1;a}
}
trong đó xác định một chức năng mà trên tất cả các cuộc gọi trả về một chức năng truy cập độc lập mới bắt đầu từ 1
:
scala> val counter1 = newCounter
counter1:() => Int = <function0>
scala> counter1()
res0: Int = 1
scala> counter1()
res1: Int = 2
scala> val counter2 = newCounter
counter2:() => Int = <function0>
scala> counter2()
res2: Int = 1
scala> counter1()
res3: Int = 3
này là khá ấn tượng như thường a
sẽ là một đại diện của địa chỉ bộ nhớ trên khung ngăn xếp của newCounter. Tôi vừa đọc chương đóng của "Lập trình trong Scala" và nó chỉ có những điều sau đây để nói về vấn đề đó (tr. 155):
Trình biên dịch Scala sắp xếp lại mọi thứ trong trường hợp như thế này sao cho tham số tồn tại trên heap, thay vì stack, và do đó có thể sống lâu hơn cuộc gọi phương thức đã tạo ra nó. Việc sắp xếp lại này được thực hiện một cách tự động, vì vậy bạn không phải lo lắng về nó.
Mọi người có thể giải thích cách hoạt động của tính năng này trên cấp mã byte không? Là truy cập tương tự như một biến thành viên của một lớp học với tất cả các đồng bộ hóa liên quan và tác động hiệu suất?
Điều này được gọi là "vấn đề funarg" và tôi đoán wiki có thể có một số gợi ý về nền tảng lý thuyết: https://en.wikipedia.org/wiki/Funarg_problem. Các giải pháp chung dường như là "đặt hồ sơ kích hoạt hoặc các phần của nó trên heap". (Google cũng có thể tìm thấy một số bài giảng/ghi chú hoặc giấy tờ về điều này.) – millimoose
Lưu ý SIP 21 "bào tử" (tên cuộc gọi!) Http://docs.scala-lang.org/sips/pending/spores.html –
Câu hỏi liên quan: http://stackoverflow.com/questions/12831024/with-scala-closures-when-do-captured-variables-start-to-live-on-the-jvm-heap –