Câu trả lời ngắn gọn: không phải vì fsi
, đó là vì có thể thay đổi được toàn cục.
Long trả lời:
Đối với một (không có thể thay đổi) chụp bình thường, thực hiện khôn ngoan giá trị bắt được sao chép vào các đối tượng chức năng, do đó nếu bạn quay trở lại chức năng này và sử dụng nó ngoài phạm vi trong đó nó đã được xác định, mọi thứ đều hoạt động tốt.
let pureAddOne() =
let x = 1
let f y = x + y // the value 1 is copied into the function object
f
let g = pureAddOne()
g 3 // x is now out of scope, but its value has been copied and can be used
Mặt khác, để nắm bắt được biến đổi, việc chụp cần được thực hiện bằng cách tham chiếu, nếu không bạn sẽ không thể sửa đổi nó. Nhưng điều này là không thể, bởi vì trong trường hợp đã đề cập trước đó, việc đóng cửa được trả về và được sử dụng ngoài phạm vi định nghĩa của nó, khả năng biến đổi cũng nằm ngoài phạm vi và có khả năng bị phân phối. Đây là lý do cho giới hạn ban đầu.
let mutableAddOne() =
let mutable x = 1
let f y = x <- x + y // x would be referenced, not copied
f
let g = mutableAddOne()
g 3 // x is now out of scope, so the reference is invalid!
// mutableAddOne doesn't compile, because if it did, then this would fail.
Tuy nhiên, nếu biến đổi là toàn cục thì không có vấn đề phạm vi nào và trình biên dịch chấp nhận. Nó không chỉ là fsi
; nếu bạn cố gắng để biên dịch chương trình sau đây với fsc
, nó hoạt động:
module Working
let mutable x = 1 // x is global, so it never goes out of scope
let mutableAddOne() =
let f y = x <- x + y // referencing a global. No problem!
f
let g = mutableAddOne()
g 3 // works as expected!
Tóm lại, như kwingho nói, nếu bạn muốn có một kết thúc cho phép chụp một giá trị có thể thay đổi địa phương, sử dụng một ref
. Chúng được cấp phát đống (ngược lại với ngăn xếp cục bộ được phân bổ theo từng ngăn xếp), miễn là việc đóng cửa giữ một tham chiếu đến nó, nó sẽ không được giải phóng.
Xin chào, nó không tạo ra đóng cửa khi bạn chỉ chạy mã body.use: let x = ref 0; let incrementX() = x: =! x + 1; xem Đóng cửa: http: //msdn.microsoft.com/en-us/library/dd233186.aspx – kwingho
Lưu ý rằng trình biên dịch cũng không phản đối phần thân của hoạt động theo cách riêng của nó. –