封装可变状态

时间:2014-02-13 16:07:47

标签: f#

我正在通过F#Wikibook工作,我已经进入了参考单元格的部分,其中出现了以下代码片段:

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

然后调用此函数三次,分别给出值1,2和3。有人可以解释为什么这个函数每次调用时都不会返回1吗?我解释这段代码的方式(这显然不是正确的解释,因此问题)是,首先,声明参考单元格'counter',内容等于0,然后是'counter'的内容增加1,然后使用匿名函数解除引用。由于incr();;的每次调用都声明“内容0的'计数器',我不明白为什么调用incr();;不会每次只返回1。

任何人都可以纠正我的理解吗?

提前致谢。

3 个答案:

答案 0 :(得分:6)

以这种方式思考:incr,而不是函数。它的值是一个捕获某些状态的闭包(即counter)。这是随后被多次调用的闭包(incr仅执行/分配一次)。也许看到等效的C#会有所帮助。

static Func<int> MakeCounter() {
    int counter = 0;
    return () => {
        counter++;
        return counter;
    };
}

var incr = MakeCounter();
incr(); //1
incr(); //2
incr(); //3

答案 1 :(得分:3)

当你调用incr()时,你正在调用incr的值,这是第3行的匿名函数。调用的代码只是匿名函数,而不是定义中的所有行。 incr

counter的初始化仅在定义incr时执行一次,而不是每次调用incr的值时都会执行。

答案 2 :(得分:3)

'incr'是一个值而不是一个函数。 它实例化'counter'然后绑定到内部函数(关闭'counter')

调用'incr'实际上是调用内部函数。 'counter'只被声明并实例化一次。