【问题标题】:SCHEME: Why does 'set!' modify a local variable of 'let'?方案:为什么“设置!”修改'let'的局部变量?
【发布时间】:2013-08-30 12:55:09
【问题描述】:

我一直在寻找一段时间,但我找不到合适的问题,所以我会发布它。我希望还没有发布。

我明白set!let是做什么的,但是我不明白为什么set!可以修改并永远保持价值。例如:

(define count
  (let ((cont 0))
    (lambda ()
      (set! cont (+ cont 1))
      cont)))

如果我们多次评估 (count),我们会看到结果是

> (count)
1
> (count)
2
> (count)
3
> 

... 等等。但是,据我了解, cont 是一个局部变量,那么为什么它会保留这个值呢?为什么每次调用函数都不设置为0?

嗯,那就是:) 提前致谢!

PS:对不起,我的英语*o*

【问题讨论】:

    标签: count scheme set let


    【解决方案1】:

    发生这种情况是因为count 正在创建一个“存储”cont 值的closure,即使在过程调用之间它也会记住它的值。请注意lambda 被分配给count 名称​​之后cont 定义为变量,这样做lambda 关闭cont。它不再是一个本地变量,它是一个在过程之外定义的变量,在它的所有调用之间共享,“记住”它在最后一次调用中的值。

    为了比较,看看具有真正局部变量的过程的外观:

    (define count
      (lambda ()
        (let ((cont 0))
          (set! cont (+ cont 1))
          cont)))
    

    上述将总是返回1,与问题中的过程进行比较。

    【讨论】:

    • 哦,我明白了。谢谢回答! :)
    • 是否每个定义变量的过程都以相同的方式表现? (记住变量的值)
    • @ee7 不,只有那些在lambda之前定义变量的。看看我编辑的答案,有一个真正的局部变量的例子,它不会在调用之间被“记住”。您必须了解闭包的概念才能了解它为什么会这样工作。
    • 哦!现在我懂了!抱歉,我在写相同的回复时只看到了您答案的第一版:P
    猜你喜欢
    • 1970-01-01
    • 2015-02-16
    • 1970-01-01
    • 2016-05-23
    • 1970-01-01
    • 1970-01-01
    • 2013-12-29
    • 1970-01-01
    • 2016-01-11
    相关资源
    最近更新 更多