सूची को बिना बांधें सीधे सूची से कई मानों को बांधें


12

क्या Emacs Lisp में एक अस्थायी वैरिएबल के माध्यम से सीधे कई वेरिएबल वैल्यूज़ को वेरिएबल में असाइन करना संभव है?

उदाहरण के लिए, मान लें कि मेरे पास एक फ़ंक्शन है जो दो सूचियों की सूची लौटाता है:

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

अगर मैं पहली रिटर्न वैल्यू list-aऔर दूसरा रिटर्न वैल्यू असाइन करना चाहता हूं list-b, तो मैं एक अस्थायी चर का उपयोग करके ऐसा कर सकता हूं 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)))

क्या यह अधिक सरल रूप से करना संभव है? (मैं पर्ल और पायथन के लिए उपयोग किया जाता हूं जहां आपको एक अस्थायी चर निर्दिष्ट करने की आवश्यकता नहीं है)


2
आप cl-destructuring-bindमैक्रो की कोशिश कर सकते हैं । इसके अलावा, क्या आप वास्तव में setqअंदर का उपयोग करने का इरादा रखते हैं defun? setqएक "विशेष" (विश्व स्तर पर सुलभ) चर बनाता है, कुछ जिसे आप आमतौर पर एक फ़ंक्शन के बाहर रखते हैं (क्योंकि एक ही चर को एक से अधिक बार घोषित करने में बहुत कम अर्थ है, जबकि कार्यों को एक से अधिक बार चलाने का इरादा है)।
wvxvw

@wvxvw धन्यवाद! हां मैं letफंक्शन के अंदर इस्तेमाल करना भूल गया .. मैंने कोई ग्लोबल वैरिएबल सेट करने की योजना नहीं बनाई :)
Håkon H 26gland

जवाबों:


8

आम लिस्प में एक विशेष सुविधा है - कई मूल्य , और Emacs लिस्प संगतता पुस्तकालय सूचियों का उपयोग करके उनका अनुकरण करता है

इस प्रकार आप कर सकते हैं

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

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

(लोड cl-libऔर cl-एलएल में सभी सीएल कार्यक्षमता के लिए उपसर्ग का उपयोग करें )।

नायब : यदि आप ऊपर दिए गए एसओ उत्तर को देखते हैं, तो आप देखेंगे कि सूचियों के साथ एमवी का अनुकरण करना है, इसे हल्के ढंग से, सबॉप्टिमल (नीचे स्टीफन की टिप्पणी भी देखें)।


क्या multiple-value-bindइसके बजाय उपयोग करने का कोई फायदा है cl-multiple-value-bind(केवल उत्तरार्द्ध मैनुअल gnu.org/software/emacs/manual/html_node/cl/Multiple-Values.html में प्रलेखित है )
हाकॉन हॉलैंड

3
@ HåkonHægland वे एक ही कार्य कर रहे हैं, लेकिन आपको बाद का उपयोग करना चाहिए । clपैकेज अब और इस्तेमाल किया जा करने के लिए नहीं है। आपको हमेशा cl-libपैकेज का उपयोग करना चाहिए , जो cl-उपसर्ग के साथ फ़ंक्शन को परिभाषित करता है ..
मालाबार

1
मैं इसके इस्तेमाल के खिलाफ सिफारिश करूंगा cl-values: यह कॉमन लिस्प का एक "सर्वोत्तम प्रयास" है, valuesलेकिन यह वास्तव में संगत नहीं है क्योंकि यह सब एक सूची है (यानी यह एक झूठ की तरह है), और मेरे अनुभव में लोग जल्दी या बाद में समाप्त होते हैं उन लोगों को सूचियों के रूप में हेरफेर करना (अर्थात अमूर्त को तोड़ना): बेहतर उपयोग सूचियों को स्पष्ट रूप से (और यदि आपको पसंद नहीं है pcase-let, तो cl-destructuring-bindइसके बजाय उपयोग करें cl-multiple-value-bind)।
स्टीफन

4

cl-libअनुकूलता पैकेज पर निर्भर होने के कारण , इसके लिए Elisp में अनुशंसित तरीका उपयोग करना है 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)))

बगल में pcase-let, वहाँ भी है pcase-dolist, pcase-lambdaऔर pcaseअपने आप में।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.