推送和添加到列表有什么区别?


27

我发现安装说明中的不同软件包都使用push或add-to-list(例如,将目录添加到load-path),我想知道它们之间的区别是什么,每种用法都有什么用。


1
我正在努力将使用add-to-list的代码转换为使用的代码cl-pushnew,我发现此博客文章很有启发性:yoo2080.wordpress.com/2013/09/11/…–
dangom

Answers:


21

#zck提到的是一个区别。但是如果那是唯一的区别,那么你可以询问cl-pushnewadd-to-list

另一个重要的区别:add-to-list是一个函数,这意味着它会评估其所有参数,尤其是第一个参数。push是一个宏(按原样cl-pushnew)-它不求值第二个参数;相反,它将其解释为一个广义的地方。

例如,如果第二个自变量是一个符号,则将其视为变量,并且第一个自变量的值作为变量被约束在该符号的值上,并将变量设置为新的不利条件。

如doc字符串所示add-to-list

This is handy to add some elements to configuration variables,
but please do not abuse it in Elisp code, where you are usually
better off using `push' or `cl-pushnew'.

6
同样根据字节编译器:add-to-list can't use lexical var ...; use push or cl-pushnew
Malabarba

(push (5 6) my-list)仍然给我一个错误- 5不是函数。这与add-to-list的行为有何不同?
markasoftware

@markasoftware:您正在尝试做什么?如果要将列表推(5 6)到该位置(变量的值),my-list则需要创建列表(5 6)。一种方法是使用'(5 6);另一种是使用(list 5 6)push计算参数。
德鲁

@Drew,您现在说它评估参数,但您的回答字面意思是“它不评估第一个参数”,这是我感到困惑的根源。
markasoftware

@markasoftware:很抱歉;我有一个错字-我写了“第一个论点”,而我本应该写“第二个论点”。现在已更正-谢谢。第二个arg to push是一个位置,例如变量。评估第一个arg,将其限制在该变量的值上,然后将该变量设置为该新变量。add-to-list计算其第一个arg以产生其值被更新的变量。push不评估其第二个arg,这是要更新的变量。两者之间的arg顺序相反。
德鲁

15

另一个区别:

push元素添加到list的开头。

add-to-list允许您将元素添加到list的开头或结尾。

(setq testasdf nil)

(push 'a testasdf)

testasdf
(a)

(add-to-list 'testasdf 'b)

testasdf
(b a)

;; add element to the end
(add-to-list 'testasdf "hello" t)

testasdf
(b a "hello")

14

Emacs文档中,或C-h f push

宏:推送元素列表名称

此宏创建一个新列表,其汽车为element,cdr为listname指定的列表,并将该列表保存在listname中。

在同一页面上,或C-h f add-to-list

功能:添加到列表符号元素和可选附加compare-fn

如果element尚未成为该值的成员,则此函数通过将element设置为旧值来设置变量符号。

因此,add-to-list仅当元素尚不存在时才进行推送。


cl-pushnew表现像add-to-list
山姆·布尔萨里斯(Sam boosalis)
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.