Answers:
#zck提到的是一个区别。但是如果那是唯一的区别,那么你可以询问cl-pushnew
和add-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'.
add-to-list can't use lexical var ...; use push or cl-pushnew
(push (5 6) my-list)
仍然给我一个错误- 5
不是函数。这与add-to-list
的行为有何不同?
(5 6)
到该位置(变量的值),my-list
则需要创建列表(5 6)
。一种方法是使用'(5 6)
;另一种是使用(list 5 6)
。push
计算参数。
push
是一个位置,例如变量。评估第一个arg,将其限制在该变量的值上,然后将该变量设置为该新变量。add-to-list
计算其第一个arg以产生其值被更新的变量。push
不评估其第二个arg,这是要更新的变量。两者之间的arg顺序相反。
从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
。
add-to-list
的代码转换为使用的代码cl-pushnew
,我发现此博客文章很有启发性:yoo2080.wordpress.com/2013/09/11/…–