set!
在方案中使用赋值运算符有什么意义?为什么不只是rebind
使用变量到新值define
?
> (define x 100)
> (define (value-of-x) x) ;; value-of-x closes over "x"
> x
100
> (value-of-x)
100
> (set! x (+ x 1))
> x
101
> (value-of-x)
101
> (define x (+ x 1))
> x
102
> (value-of-x)
102
>
Run Code Online (Sandbox Code Playgroud)
Kyl*_*nin 39
虽然双方define
并set!
当在同一范围内,他们做两个不同的东西时,范围不同将重新定义的值.这是一个例子:
(define x 3)
(define (foo)
(define x 4)
x)
(define (bar)
(set! x 4)
x)
(foo) ; returns 4
x ; still 3
(bar) ; returns 4
x ; is now 4
Run Code Online (Sandbox Code Playgroud)
如您所见,当我们创建一个新的词法范围(例如当我们define
是一个函数)时,该范围内定义的任何名称都会掩盖显示在封闭范围内的名称.这意味着,当我们define
ð x
到4
在foo
,我们确实创造了一个新的值x
是阴影的旧值.在bar
,由于foo
在该范围内不存在,set!
查看封闭范围以查找和更改其值x
.
此外,正如其他人所说,你只应该define
在范围内使用一次名字.一些实现将让你逃脱多个define
s,而有些则不会.此外,您只应该使用set!
已经存在的变量define
.同样,强制执行此规则的严格程度取决于实施.
通常不允许define
变量多于一次.当你尝试解决问题时,大多数REPL允许它方便,但如果你试图在Scheme程序中这样做,它会给你一个错误.
例如,在mzscheme中,该程序
#lang scheme
(define x 1)
(define x 2)
Run Code Online (Sandbox Code Playgroud)
给出了错误
test.ss:3:8: module: duplicate definition for identifier at: x in: (define-values (x) 2)
Run Code Online (Sandbox Code Playgroud)
另外,define
在其他上下文中使用时具有不同的含义.该程序
#lang scheme
(define x 1)
x
(let ()
(define x 2)
x)
x
Run Code Online (Sandbox Code Playgroud)
有输出
1
2
1
Run Code Online (Sandbox Code Playgroud)
这是因为define
某些结构中的letrec
s 实际上被视为s.
归档时间: |
|
查看次数: |
18776 次 |
最近记录: |