我是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?我尝试了其他几个函数(cons
,list
)但结果是相同的/相似的 - 3未添加到原始列表中。
答案 0 :(得分:2)
所以你是push
一个值到一个作为函数参数传递的列表?这不起作用; push创建一个新的cons单元格,使其指向原始列表,并设置变量以引用新的cons单元格。不幸的是,在函数中设置函数参数并不对最初传递的变量(从函数外部)做任何事情。
调用函数时,首先计算参数。因此,如果将l
传递给函数,实际传递的是l
的值。函数内部没有任何内容可以改变l
引用的内容(函数外部)。
如果要创建类似函数的东西,但实际上更改了用作参数的变量的值,则需要编写宏。或者,只需使函数返回所需的值,并在返回返回值后将原始变量设置在函数外部。像这样:
(setf l (my-function l))
或者,您可以使用额外的间接级别:make l
引用“虚拟”cons单元格,它指向“真实”列表,并更改“虚拟”的cdr
“从你的职能范围内收缩。然而,这种风格很差;通常最好使用返回值,而不是在修改后的参数中“返回”数据。
请注意,如果您需要返回多个值,这并不意味着您需要修改参数; Common Lisp可以使用(values)
从函数返回多个值。