Krótka odpowiedź: nie ze względu na fsi
, ponieważ zmienna jest globalna.
Długa odpowiedź:
Dla normalnego (non-zmienny) chwytania, realizacja mądry zrobionego wartość jest kopiowana do obiektu funkcji, tak, że jeśli wrócisz tę funkcję i używać go poza zakresem, w którym zostało to zdefiniowane, wszystko działa dobrze.
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
Z drugiej strony, w celu przechwycenia zmienny, przechwytywanie należy zrobić odniesienie, w przeciwnym razie nie byłby w stanie go zmienić. Ale jest to niemożliwe, ponieważ we wcześniej wspomnianym przypadku, gdy zamknięcie jest zwracane i używane poza zakresem jego definicji, zmienna jest również poza zakresem i potencjalnie deallocated. To jest powód początkowego ograniczenia.
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.
Jeśli jednak zmienna jest globalna, wówczas nie ma problemu z takim zakresem, a kompilator je akceptuje. To nie tylko fsi
; Jeśli spróbujesz skompilować następujący program z fsc
, to działa:
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!
Podsumowując, jak kwingho powiedział, jeśli chcesz mieć zamknięcie, które przechwytuje lokalną wartość zmienny, użyj ref
. Są one przydzielane do sterty (w przeciwieństwie do alokowanego w stosie lokalnego mutable), o ile zamknięcie zawiera odniesienie do niego, nie zostanie ono zwolnione.
Cześć, nie generuje zamknięcia po prostu po uruchomieniu kodu ciała.use: let x = ref 0; niech incrementX() = x: =! x + 1; zobacz: Zamknięcia: http: //msdn.microsoft.com/en-us/library/dd233186.aspx – kwingho
Zauważ, że kompilator także nie sprzeciwia się treści działa samodzielnie. –