【问题标题】:variable defined inside a procedure is kept?保留过程中定义的变量?
【发布时间】:2014-02-14 19:57:53
【问题描述】:

我写了一个程序(do-test)。 由于测试可能会对变量env 产生一些影响, 我在do-test 中定义了env,希望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找到我的代码beforeafter的变化)

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

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

【问题讨论】:

    标签: mit-scheme guile


    【解决方案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) 视为一个常量,并且该列表仅分配一次,无论它被调用多少次。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-11-18
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多