Яка різниця між натисканням та доповненням до списку?


28

Я виявив, що різні пакунки в інструкціях по установці використовують або push або доповнення до списку (наприклад, додавання каталогу до load-path), і мені було цікаво, в чому різниця і в чому полягатиме випадок використання для кожного.


1
Я намагався перетворити код з використанням add-to-listкоду cl-pushnew, і я вважав, що ця публікація в блозі є досить захоплюючою: yoo2080.wordpress.com/2013/09/11/…
dangom

Відповіді:


22

Що згадує #zck - це одна різниця. Але якби це була єдина відмінність, тоді ви могли б запитати про cl-pushnewі add-to-list.

Ще одна важлива відмінність: add-to-listце функція, яка означає, що вона оцінює всі свої аргументи, зокрема перший. pushє макросом (як є cl-pushnew) - він не оцінює свій другий аргумент; натомість вона трактує це як узагальнене місце.

Наприклад, якщо другий аргумент є символом, то він розглядається як змінна, а значення першого аргументу передається на значення цього символу як змінної, а змінна встановлюється на ці нові мінуси.

Як add-to-listговорить рядок doc :

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
Малабарба

(push (5 6) my-list)все ще дає мені помилку - 5це не функція. Чим це відрізняється від add-to-listповедінки Росії?
markasoftware

@markasoftware: Що ви намагаєтеся зробити? Якщо ви хочете натиснути список (5 6)на місце (значення змінної), my-listвам потрібно створити список (5 6). Один із способів зробити це - використовувати '(5 6); інший - використовувати (list 5 6). pushоцінює аргумент.
Дрю

@Здавай, ти кажеш, що вона оцінює аргумент, але у твоєму відповіді буквально сказано, що "він не оцінює свій перший аргумент", що є джерелом моєї плутанини.
markasoftware

@markasoftware: Вибачте; У мене був помилка друку - я написав "перший аргумент", де я повинен був написати "другий аргумент". Виправлено зараз - спасибі. Другий аргумент to push- це місце, наприклад змінна. Перший аргумент оцінюється, передається на значення цієї змінної, і змінна встановлюється до нових мінусів. add-to-listоцінює свій перший аргумент для створення змінної, значення якої оновлюється. pushне оцінює свій другий аргумент, який є змінною для оновлення. Порядок аргументів повернений між двома.
Дрю

15

З документації Emacs або C-h f push:

Макрос: ім'я списку натискання елементів

Цей макрос створює новий список, автомобіль якого є елементом і cdr - список, визначений listname, і зберігає цей список у listname.

З тієї ж сторінки, або C-h f add-to-list:

Функція: елемент символу додавання до списку та додаткове додавання порівняння-fn

Ця функція встановлює символ змінної шляхом перенесення елемента на старе значення, якщо елемент ще не є членом цього значення.

Тож add-to-listнатискає лише, якщо елемента вже немає.


cl-pushnewповодиться як add-to-list.
sam boosalis

15

Ще одна відмінність:

pushдодає елемент на початок списку .

add-to-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")
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.