Переменная, определенная внутри процедуры, сохраняется?
Я написал процедуру (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-schema / guile / codepad.org, и все это мне подсказывало (do-test)
дважды давал разные результаты.
Но если я изменю линию (define env '(1))
в (define env (list 1))
Я получу ожидаемый результат. (вы можете найти мой код до и после изменения в codepad.org)
Насколько мне известно, '(1)
а также (list 1)
должно быть таким же, за исключением того, что второй будет процедура вызова list
,
Мне интересно, почему это происходит и как я могу предотвратить повторное использование программой предыдущих значений?
1 ответ
Пожалуйста, посмотрите на 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)
как константа, и этот список выделяется только один раз, независимо от того, сколько раз он вызывается.