将元素添加到全局变量

时间:2012-02-18 21:53:28

标签: common-lisp

我是lisp的新手,在向现有列表添加元素时遇到问题。

> (setq l '(1 2))
(1 2)
> (append l 3)
(1 2 . 3)
> l
(1 2)
> (append l '(3))
(1 2 3)
> l
(1 2)
> (list l '(3))
((1 2) (3))
> l
(1 2)
> (cons 3 l)
(3 1 2)
> l
(1 2)
> (push 3 l)
(3 1 2)
> l
(3 1 2)

以上示例是我在命令行上创建的。这里只有push有效。但是当我执行我在文件中编写的代码(并在命令行上加载它)时,即使push也不添加元素。我的代码示例可用in another question's page

如何更新原始l以便为自己添加3?我尝试了其他几个函数(conslist)但结果是相同的/相似的 - 3未添加到原始列表中。

1 个答案:

答案 0 :(得分:2)

所以你是push一个值到一个作为函数参数传递的列表?这不起作用; push创建一个新的cons单元格,使其指向原始列表,并设置变量以引用新的cons单元格。不幸的是,在函数中设置函数参数并不对最初传递的变量(从函数外部)做任何事情。

调用函数时,首先计算参数。因此,如果将l传递给函数,实际传递的是l。函数内部没有任何内容可以改变l引用的内容(函数外部)。

如果要创建类似函数的东西,但实际上更改了用作参数的变量的值,则需要编写。或者,只需使函数返回所需的值,并在返回返回值后将原始变量设置在函数外部。像这样:

(setf l (my-function l))

或者,您可以使用额外的间接级别:make l引用“虚拟”cons单元格,它指向“真实”列表,并更改“虚拟”的cdr “从你的职能范围内收缩。然而,这种风格很差;通常最好使用返回值,而不是在修改后的参数中“返回”数据。

请注意,如果您需要返回多个值,这并不意味着您需要修改参数; Common Lisp可以使用(values)从函数返回多个值。