Jaka jest różnica między wypychaniem a dodawaniem do listy?
28
Przekonałem się, że różne pakiety w instrukcjach instalacji używają push lub add-to-list (na przykład dodając katalog do ścieżki ładowania) i zastanawiałem się, jaka jest różnica i jaki byłby przypadek użycia każdego z nich.
Próbowałem przekonwertować kod za pomocą add-to-listna kod za pomocą cl-pushnewi uważam, że ten post na blogu jest dość pouczający: yoo2080.wordpress.com/2013/09/11/…
dangom,
Odpowiedzi:
22
To, o czym wspomina #zck, to jedna różnica. Ale gdyby to była jedyna różnica, możesz zapytać o cl-pushnewi add-to-list.
Kolejna ważna różnica: add-to-listjest funkcją, która oznacza, że ocenia wszystkie argumenty, w szczególności pierwszy. pushjest makrem (jak jest cl-pushnew) - nie ocenia drugiego argumentu; zamiast tego interpretuje to jako uogólnione miejsce.
Na przykład, jeśli drugi argument jest symbolem, wówczas jest on traktowany jako zmienna, a wartość pierwszego argumentu jest traktowana jako wartość tego symbolu jako zmienna, a zmienna jest ustawiana na te nowe minusy.
Jak add-to-listmówi ciąg dokumentów :
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'.
Również według bajtowego kompilatora:add-to-list can't use lexical var ...; use push or cl-pushnew
Malabarba
(push (5 6) my-list)wciąż daje mi błąd - 5nie jest funkcją. Czym różni się to od add-to-listzachowania?
markasoftware
@markasoftware: Co próbujesz zrobić? Jeśli chcesz przesunąć listę (5 6)na miejsce (wartość zmiennej) my-list, musisz utworzyć listę (5 6). Jednym ze sposobów na to jest użycie '(5 6); innym jest użycie (list 5 6). pushocenia argument.
Drew
@Drew, mówisz teraz, że ocenia argument, ale twoja odpowiedź dosłownie brzmi „nie ocenia pierwszego argumentu”, co jest źródłem mojego zamieszania.
markasoftware
@markasoftware: Przepraszam; Miałem literówkę - napisałem „pierwszy argument”, w którym powinienem napisać „drugi argument”. Poprawione teraz - dzięki. Drugim argumentem pushjest miejsce, takie jak zmienna. Pierwszy argument jest obliczany, przetwarzany na wartość tej zmiennej, a zmienna jest ustawiana na te nowe minusy. add-to-listocenia swój pierwszy argument, aby wygenerować zmienną, której wartość jest aktualizowana. pushnie ocenia drugiego argumentu, który jest zmienną do aktualizacji. Kolejność arg jest odwrócona między nimi.
add-to-listpozwala dodać element na początku lub na końcu listy .
(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")
add-to-list
na kod za pomocącl-pushnew
i uważam, że ten post na blogu jest dość pouczający: yoo2080.wordpress.com/2013/09/11/…Odpowiedzi:
To, o czym wspomina #zck, to jedna różnica. Ale gdyby to była jedyna różnica, możesz zapytać o
cl-pushnew
iadd-to-list
.Kolejna ważna różnica:
add-to-list
jest funkcją, która oznacza, że ocenia wszystkie argumenty, w szczególności pierwszy.push
jest makrem (jak jestcl-pushnew
) - nie ocenia drugiego argumentu; zamiast tego interpretuje to jako uogólnione miejsce.Na przykład, jeśli drugi argument jest symbolem, wówczas jest on traktowany jako zmienna, a wartość pierwszego argumentu jest traktowana jako wartość tego symbolu jako zmienna, a zmienna jest ustawiana na te nowe minusy.
Jak
add-to-list
mówi ciąg dokumentów :źródło
add-to-list can't use lexical var ...; use push or cl-pushnew
(push (5 6) my-list)
wciąż daje mi błąd -5
nie jest funkcją. Czym różni się to odadd-to-list
zachowania?(5 6)
na miejsce (wartość zmiennej)my-list
, musisz utworzyć listę(5 6)
. Jednym ze sposobów na to jest użycie'(5 6)
; innym jest użycie(list 5 6)
.push
ocenia argument.push
jest miejsce, takie jak zmienna. Pierwszy argument jest obliczany, przetwarzany na wartość tej zmiennej, a zmienna jest ustawiana na te nowe minusy.add-to-list
ocenia swój pierwszy argument, aby wygenerować zmienną, której wartość jest aktualizowana.push
nie ocenia drugiego argumentu, który jest zmienną do aktualizacji. Kolejność arg jest odwrócona między nimi.Z dokumentacji Emacsa lub
C-h f push
:Z tej samej strony lub
C-h f add-to-list
:add-to-list
Pcha więc tylko wtedy, gdy elementu już nie ma.źródło
cl-pushnew
zachowuje się jakadd-to-list
.Kolejna różnica:
push
dodaje element na początku listy .add-to-list
pozwala dodać element na początku lub na końcu listy .źródło