我想要的清单传递给Lisp的功能,并且在函数内部改变该列表中的内容,而不会影响原有的列表中。我读过Lisp是传递的价值,这是真的,但有别的事情上,我不太明白。例如,该代码可以按预期:

(defun test ()
    (setf original '(a b c))
    (modify original)
    (print original))
(defun modify (n)
    (setf n '(x y z))
    n)

如果你调用(测试),它打印(A B C)即使(修改)返回(X Y Z)。

但是,它不一样,如果你试图改变只是名单的一部分工作方式。我认为这事做与具有相同的内容是在内存中随处可见或类似的东西,同样的名单?下面是一个例子:

(defun test ()
    (setf original '(a b c))
    (modify original)
    (print original))
(defun modify (n)
    (setf (first n) 'x)
    n)

然后(测试)打印(X B C)。那么,如何改变一个列表参数的一些元素的功能,因为如果该列表是局部的功能?

有帮助吗?

解决方案

SETF修改一个地方n可以是一个地方。列表n点的第一个元素也可以是一个地方。

在这两种情况下,通过保持original列表传递给modify作为其参数n。这意味着,在该函数originaltest在功能n两者modify现在持有相同的列表,这意味着这两个originaln现在指向其第一个元素。

SETF在第一种情况下修改n之后,它不再指向列表中,但以一个新的列表。清单指向original不受影响。新的列表,然后通过modify返回,但由于该值未分配到任何东西,它淡出存在,并且将很快被垃圾收集。

在第二种情况下,SETF会修改不n,但列表n指向的第一个元素。这是相同的列表original点,所以,后来,你也可以看到通过这个变量修改的列表。

在以复制列表,使用 COPY-LIST

其他提示

Lisp的列表是基于利弊细胞。变量等指针缺点细胞(或其它的Lisp对象)。改变某个变量将不会改变其他变量。更改利弊细胞就会看到在那里有那些利弊细胞引用的所有地方。

有一个良好的开端是Touretzky,的Common Lisp:一个温柔的介绍符号计算

还有,吸引列表和缺点细胞的树木的软件。

如果你传递一个列表给函数是这样的:

(modify (list 1 2 3))

然后你有三种不同的方式使用的列表:

利弊的破坏性变形细胞

(defun modify (list)
   (setf (first list) 'foo)) ; This sets the CAR of the first cons cell to 'foo .

<强>结构共享

(defun modify (list)
   (cons 'bar (rest list)))

以上返回一个列表股结构与传递的列表:其余元件是在两个列表中相同的

<强>复制

(defun modify (list)
   (cons 'baz (copy-list (rest list))))

以上功能BAZ类似于BAR,但没有列表中的小区是共享的,因为该列表将被复制。

不用说,破坏性修饰通常应避免,除非有一个真正的理由这样做(如节省存储器时,它是值得的)。

注意:

<强>从未破坏性修改常量列表

不要 'DO:(让((L'(A B C)))(SETF(第一升)“巴))

原因:该列表可被写保护,或者可以与其他列表(由编译器布置)被共享,等

此外:

<强>介绍变量

这样

(let ((original (list 'a 'b 'c)))
   (setf (first original) 'bar))

或类似这样的

(defun foo (original-list)
   (setf (first original-list) 'bar))

从未SETF未定义的变量。

它几乎是相同的在C本例中:

void modify1(char *p) {
    p = "hi";
}

void modify2(char *p) {
    p[0] = 'h';
}

在这两种情况下指针传递,如果你改变了指针,你改变指针值的参数拷贝(它的堆栈上),如果你改变的内容,你改变的任何值对象指出。

您可能有问题,因为即使Lisp是通过按值对对象的引用被传递,就像Java或Python。你的缺点单元包含修改引用,所以你修改原件和地方之一。

海事组织,你应该尝试写功能更实用的风格,以避免此类问题。即使Common Lisp是多范式的官能风格是一个比较合适的方式。

(defun定义修改(n)的    (利弊“×(CDR n))的

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top