Listenin kendisini bağlamadan birden çok değeri doğrudan listeden bağlama


12

Emacs Lisp'de geçici bir değişken olmadan doğrudan değişkenlere birden fazla dönüş değeri atamak mümkün müdür?

Örneğin, iki listenin listesini döndüren bir işlevim olduğunu varsayalım:

(defun test-func ()
  (setq a '(a b))
  (setq b '(c d))
  `(,a ,b))

İlk dönüş değerini list-ave ikinci dönüş değerini atamak istersem , örneğin list-bgeçici bir değişken kullanarak bunu yapabilirim temp:

(let* ((temp (test-func)) (list-a (car temp)) (list-b (cadr temp)))
  (message-box (prin1-to-string list-a))
  (message-box (prin1-to-string list-b)))

Bunu daha basit yapmak mümkün mü? (Geçici bir değişken belirtmeniz gerekmeyen Perl ve Python'a alışkınım)


2
cl-destructuring-bindMakroyu deneyebilirsiniz . Ayrıca, gerçekten setqbir içinde kullanmak istediniz defunmi? setq"özel" (küresel olarak erişilebilir) bir değişken oluşturur, genellikle bir işlevin dışına koyacağınız bir şeydir (çünkü aynı değişkeni bir kereden fazla bildirmenin anlamı yoktur, ancak işlevler birden çok kez çalıştırılmak üzere tasarlanmıştır).
wvxvw

@wvxvw Teşekkürler! Evet letfonksiyonun içinde kullanmayı unuttum .. Global bir değişken belirlemeyi
düşünmedim

Yanıtlar:


8

Ortak Lisp özel bir özelliğe sahiptir - birden fazla değer ve Emacs Lisp uyumluluk kütüphanesi listeleri kullanarak bunları taklit eder .

Böylece yapabilirsin

(defun test-fun ()
  (let ((a 1) (b 2))
    (cl-values a b)))

(cl-multiple-value-bind (a b) (test-fun)
  ...)

( EL'deki tüm CL işlevleri cl-libiçin cl-öneki yükleyin ve kullanın ).

Not : yukarıda bağlanan SO cevabına bakarsanız, MV'yi listelerle taklit etmenin hafifçe koymak için yetersiz olduğunu göreceksiniz (ayrıca aşağıdaki @ Stefan'ın yorumuna bakın).


multiple-value-bindBunun yerine kullanmanın herhangi bir avantajı var mı cl-multiple-value-bind(yalnızca ikincisi gnu.org/software/emacs/manual/html_node/cl/Multiple-Values.html kılavuzunda belgelenmiş gibi görünüyor )?
Håkon Hægland

3
@ HåkonHægland Aynı işlevler, ancak ikincisini kullanmalısınız . clPaket artık kullanılmak üzere tasarlanmamıştır. Her zaman cl-libbunun yerine paketi kullanmalısınız, bu da cl-önek ile fonksiyonları tanımlar ..
Malabarba

1
Kullanımına karşı tavsiye ederim cl-values: CommonLisp'in "en iyi çabası" öykünmesi, valuesancak tek yaptığı bir liste döndürmek (yani bir tür yalan) olduğu için gerçekten uyumlu değil ve deneyimlerime göre insanlar er ya da geç sonunda Bunları liste olarak değiştirmek (yani soyutlamayı kırmak): listeleri açıkça daha iyi kullanın (ve beğenmiyorsanız pcase-let, kullanmak cl-destructuring-bindyerine cl-multiple-value-bind).
Stefan

4

cl-libUyumluluk paketine güvenmenin yanı sıra , Elisp'te bunun için önerilen yöntem pcase:

(defun test-fun
  (let ((a '(a b))
        (b '(c d)))
    `(,a ,b)))

(defun other-test-fun ()
  (pcase-let ((`(,a ,b) (test-fun)))
    (message "a = %s; b = %s" a b)))

Yanında pcase-let, orada da var pcase-dolist, pcase-lambdave pcasekendisi.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.