gpt4 book ai didi

list - 插入到列表中不反射(reflect)外部功能,而删除呢?

转载 作者:太空宇宙 更新时间:2023-11-03 18:58:51 26 4
gpt4 key购买 nike

我是 Lisp 新手。函数删除列表中的项目会反射(reflect)在函数外部,但插入不会。我怎样才能对插入做同样的事情?

例如

(defun test (a b)
(delete 1 a)
(delete 5 b)
(append '(5) b)
(member '5 b))

(setq x '(2 3 1 4))
(setq y '(8 7 5 3))

(test x y)

;;x and y after function ends
x
(2 3 4)
y
(8 7 3)

为什么 append 不影响列表 y?如何从函数内向 y 中插入内容?

最佳答案

Append 不是应该修改任何东西

Why doesn't append affect list y?

关于的文档第一句append 是(添加了重点):

append returns a new list that is the concatenation of the copies.

从来没有人说过 append 应该修改一个列表。

你不能在其作用域之外改变词法绑定(bind)的值

How can I insert something into y from within the function?

在最一般的意义上,你不能。如果 y 的值为空列表会怎样? 函数(与宏相反)无法在 Common Lisp 中实现这样的功能:

(let ((list '())
(insert list 1)
l)
;=> (1)

函数不能改变其作用域外的变量的词法绑定(bind)1,所以insert无法改变list的值>。

当然,您可以修改对象的内部结构,因此如果list 的值是某个非空列表,那么您可以修改该列表的结构。 list 的值不会改变(即,它仍然是相同的 cons 单元),但由该 cons 单元表示的列表会改变。例如,

(defun prepend (list element)
(let ((x (first list)))
(setf (rest list) (list* x (rest list))
(first list) element)))

(let ((list (list 1 2)))
(prepend list 'a)
list)
;=> (a 1 2)

保存返回值

一般来说,你需要养成保存函数结果的习惯。大多数函数不会修改它们的参数,因此您需要保存它们的结果。某些函数允许必需修改它们的参数,并且它们不必以可预测的方式进行修改,因此您也需要保存它们的结果。例如,您的代码可以是:

(defun test (a b)
(setf a (delete 1 a))
(setf b (delete 5 b))
(setf b (append '(5) b))
(member 5 b))

(test ...)
;=> true

1 您可以通过为它提供一个关闭绑定(bind)等的 setter 函数来解决此问题。但这些技术将是解决方法

关于list - 插入到列表中不反射(reflect)外部功能,而删除呢?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30844742/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com