1

我写了一个程序(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 中找到更改前后的代码

据我所知,'(1)应该(list 1)是相同的,除了第二个将调用过程list

我想知道为什么会发生这种情况以及如何防止程序重用以前的值?

4

1 回答 1

0

请看一下R5RS,上面说

set-car!使用类似or 的变异过程来改变常量(即文字表达式的值)是错误的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)视为常量,并且该列表仅分配一次,无论调用多少次。

于 2014-02-05T23:16:09.887 回答