我写了一个程序(do-test)
。
由于测试可能会对变量env
产生一些影响,
我在env
内定义do-test
,希望env
不会被携带
随着程序,所以每次我运行它,我将获得一个新的环境来工作。
令我惊讶的是,我的测试程序实际上是前一个env
。
请找到以下代码:
(define (do-test)
(define env '(1))
;(define env (list 1))
(display env)
(if (not (equal? (car env) 1))
(error "assertion failed.")
'ok)
(set-car! env 2)
'ok)
(do-test)
(do-test)
我尝试使用mit-scheme / guile / codepad.org运行此代码,以及所有这些代码
告诉我两次跑(do-test)
会产生不同的结果。
但如果我将行(define env '(1))
更改为(define env (list 1))
,我会得到预期的结果。
(您可以在codepad.org中找到我的代码before和after)
据我所知,'(1)
和(list 1)
应该相同,只是第二个是调用程序list
。
我想知道为什么会发生这种情况,如何防止程序重复使用以前的值?
答案 0 :(得分:0)
请查看R5RS,其中说明了
更改常量(即文字的值)是错误的 表达式)使用像
set-car!
或。string-set!
这样的变异过程'(1)
。
因此(list 1)
和(define (f) (list 1))
(define (g) '(1))
(display (eq? (f) (f)))(newline)
(display (eq? (g) (g)))(newline)
并不完全相同:当您打算构建将来会发生变异的某些数据时,请不要使用引号。
如果您尝试这样做:
#f
#t
你会得到:
f
这表明g
会在每次调用时生成一个列表。但是'(1)
会将其列表{{1}}视为常量,并且该列表只会被分配一次,无论它被调用多少次。