了解给定代码中的变量范围
Understanding variable scope in given code
我是 Emacs lisp 的初学者,所以这确实是一个菜鸟问题。假设我必须编写一个函数,该函数使用循环将数字向量的每个元素加 1。
这是我写的代码(注释表明我在每一步尝试做什么):
(defun add-one (x)
"Use a loop to add 1 to each element of list X"
(let* ((res x) ; make a copy of X
(counter 0)) ; set counter to 0
(while (< counter (length x))
;; Replace each element of RES by adding 1:
(setcar (nthcdr counter res) (1+ (car (nthcdr counter x))))
(setq counter (1+ counter)))
;; Display result:
(message "%s" res)))
但我的代码似乎对 x
具有破坏性,因为对该函数的多次调用不会产生相同的结果:
;; Define a list:
(setq mylist '(1 2 3 4))
;; Several calls to the function:
(add-one mylist) ; -> (2 3 4 5)
(add-one mylist) ; -> (3 4 5 6)
这是我的问题:我不明白为什么我的代码具有破坏性(我预计每次执行的结果都是 (2 3 4 5)
)。我知道 setcar
具有破坏性,但它应用于 x
的副本,而不是 x
本身。那为什么结果变了?
谢谢!
Let 不会复制任何东西,所以这会将变量 x
引用的值赋给变量 res
。因此,对 res
引用的列表的任何更改也会更改 x
引用的列表
(let* ((res x) ; make a copy of X
为了清楚起见:
尽管您没有复制输入列表,但您的代码一点也不 lispy。试试这个:
(mapcar '1+ '(1 2 3 4))
我是 Emacs lisp 的初学者,所以这确实是一个菜鸟问题。假设我必须编写一个函数,该函数使用循环将数字向量的每个元素加 1。
这是我写的代码(注释表明我在每一步尝试做什么):
(defun add-one (x)
"Use a loop to add 1 to each element of list X"
(let* ((res x) ; make a copy of X
(counter 0)) ; set counter to 0
(while (< counter (length x))
;; Replace each element of RES by adding 1:
(setcar (nthcdr counter res) (1+ (car (nthcdr counter x))))
(setq counter (1+ counter)))
;; Display result:
(message "%s" res)))
但我的代码似乎对 x
具有破坏性,因为对该函数的多次调用不会产生相同的结果:
;; Define a list:
(setq mylist '(1 2 3 4))
;; Several calls to the function:
(add-one mylist) ; -> (2 3 4 5)
(add-one mylist) ; -> (3 4 5 6)
这是我的问题:我不明白为什么我的代码具有破坏性(我预计每次执行的结果都是 (2 3 4 5)
)。我知道 setcar
具有破坏性,但它应用于 x
的副本,而不是 x
本身。那为什么结果变了?
谢谢!
Let 不会复制任何东西,所以这会将变量 x
引用的值赋给变量 res
。因此,对 res
引用的列表的任何更改也会更改 x
(let* ((res x) ; make a copy of X
为了清楚起见: 尽管您没有复制输入列表,但您的代码一点也不 lispy。试试这个:
(mapcar '1+ '(1 2 3 4))