Apa perbedaan antara setq dan defvar

14

Apa perbedaan antara setqdan defvardi Emacs lisp?

Saya melihat versi umum lump dari pertanyaan yang sama di /programming/3855862 . Apakah mereka sama di Elisp?

Yasushi Shoji
sumber

Jawaban:

18

Anda harus bertanya kepada Emacs pertanyaan ini :, C-h ipilih manual Elisp ( m Elisp), dan cari indeks untuk "defvar" ( i defvar). Itu akan membawa Anda ke node Mendefinisikan Variabel .

Emacs memberi tahu Anda bahwa defvarmemungkinkan melampirkan string doc , dan bahwa jika variabel sudah memiliki nilai maka tidak ada artinya .

Ia juga memberitahu Anda tentang penggunaan defvardengan tidak ada nilai ditugaskan: (defvar foo). Ini memberitahu Anda bahwa yang menyatakan variabel untuk dicakup secara dinamis .

setq tidak memiliki properti tersebut.

defvardan setqserupa, tetapi tidak persis sama, di Emacs Lisp dan Common Lisp.

Baca lebih lanjut, untuk mempelajari lebih lanjut.

Drew
sumber
1
Bahkan defvar juga menyatakan "pelingkupan dinamis" jika ada nilai yang diberikan, dan itu tetap benar bahkan jika variabel sudah memiliki nilai. OTOH "jika variabel sudah memiliki nilai maka tidak melakukan apa-apa" adalah benar untuk semua penggunaan defvar yang valid (dan bytecompiler harus mengeluarkan peringatan dalam kasus-kasus yang tersisa, yaitu jika mendeklarasikan variabel setelah penggunaan pertama).
YoungFrog
jadi kedengarannya seperti defvarvariabel global (seperti dalam gaya pemrograman imperatif) dan konvensi untuk kustomisasi, sementara setq lebih seperti ikatan yang mengikat dalam bahasa pemrograman fungsional (dengan aturan pelingkupan dinamis / leksikal tergantung pada mode pelingkupan global mana yang aktif .. .......)
nicolas
@nicolas: Silakan baca manualnya. setqmenetapkan nilai var, terlepas dari apakah var (kejadian) adalah lokal. defvarmendeklarasikan var sebagai global. (Ini mungkin juga "buffer-local":. local-variable-p) Suatu kejadian var terikat sebagai fungsi arg atau oleh letadalah "lokal" dalam arti biasa. Jika var terikat oleh letdll. Adalah global (atau buffer-lokal) maka mengikat lokal (akal biasa) dibuat untuk itu, untuk durasi / ruang lingkup itu let. Dalam ruang lingkup yang mengikat itu, setqmengubah nilai lokal. Lebih baik berbicara tentang kejadian var menjadi lokal (di stack) atau global (di tumpukan) daripada var begitu.
Drew
1
@nicolas: Luangkan waktu Anda untuk membacanya dan baca ulang. Terkadang apa yang dikatakannya tepat tetapi sulit untuk dipahami, seperti spesifikasi formal. Setelah Anda mendapatkannya, mungkin bermanfaat bagi Anda M-x report-emacs-buguntuk menyarankan perbaikan yang mungkin membantu orang lain untuk membuatnya lebih mudah.
Drew
1
@nicolas: Mulailah dengan memahami variabel di heap (alias variabel global atau buffer-local). Anda mungkin sudah memahami variabel lokal sebenarnya, yaitu variabel di stack . Googling juga dapat membantu.
Drew