Возврат функции с закрытием


Следующий код:

let CreateFunc=
    let counter = ref 0
    fun () -> counter := !counter + 1; !counter

let f1 = CreateFunc
let f2 = CreateFunc

printfn "%d" (f1())
printfn "%d" (f1())
printfn "%d" (f2())
printfn "%d" (f2())

Выходы:

1
2
3
4
Таким образом, в основном, то, что мы видим здесь, - это f1 и f2, являющиеся одной и той же функцией, поскольку они, очевидно, используют один и тот же экземпляр "счетчика".

Ожидаемый результат:

1
2
1
2

Вопрос: разве f1 и f2 не должны быть двумя отдельными экземплярами? В конце концов, они создаются двумя различными вызовами "CreateFunc"???

Спасибо

1 6
f#

1 ответ:

let CreateFunc() =
    let counter = ref 0
    fun () -> counter := !counter + 1; !counter

let f1 = CreateFunc()
let f2 = CreateFunc()

printfn "%d" (f1())
printfn "%d" (f1())
printfn "%d" (f2())
printfn "%d" (f2())

Выход -

1
2
1
2

Пояснение:

В вашем исходном решении CreateFunc была функция, но всегда одна и та же функция (CreateFunc, f1 и f2 все были синонимами, указывающими на одну и ту же функцию). В моем решении CreateFunc является функцией, которая возвращает новую функцию всякий раз, когда она вызывается, таким образом, каждая функция имеет свое собственное состояние (т. е. counter).

Короче говоря: первоначальное CreateFunc было значением, всегда одним и тем же значением.