2012-01-19 5 views
31

के बीच क्या अंतर है मुझे Similar question मिला।डिफवर, डिफपरमीटर, सेटफ और सेटक

लेकिन मुझे स्पष्टीकरण समझ में नहीं आता है।

तो मैं निम्न उदाहरण के साथ clisp को चलाने के लिए कोशिश कर रहा हूँ:

[1]> (defvar a 5) 
    A 
    [2]> (+ a 1) 
    6 
    [3]> (defparameter b 5) 
    B 
    [4]> (+ b 1) 
    6 
    [5]> (setf c 5) 
    5 
    [6]> (+ c 1) 
    6 
    [7]> (setq d 5) 
    5 
    [8]> (+ d 1) 
    6 
    [9]> (let ((a 500)) (+ a 1)) 
    501 
    [10]> (let ((b 500)) (+ b 1)) 
    501 
    [11]> (let ((c 500)) (+ c 1)) 
    501 
    [12]> (let ((d 500)) (+ d 1)) 
    501 
    [13]> 

मैं क्या पाया पूरी तरह से एक ही है।

मैं यह नहीं समझ सकता कि उनके साथ क्या अलग है?

उत्तर

55

DEFPARAMETER हमेशा एक मान निर्दिष्ट करता है। तो:

[1]> (defparameter a 1) 
A 
[2]> (defparameter a 2) 
A 
[3]> a 
2 

DEFVAR यह करता है, जबकि केवल एक बार, तो:

[4]> (defvar b 1) 
B 
[5]> (defvar b 2) 
B 
[6]> b 
1 

SETF एक मैक्रो जो आंतरिक रूप से SETQ का उपयोग करता है, लेकिन अधिक संभावनाएं है है। एक तरह से यह एक अधिक सामान्य असाइनमेंट ऑपरेटर है। जैसे SETF साथ आप कर सकते हैं:

[19]> (defparameter c (list 1 2 3)) 
[21]> (setf (car c) 42)            
42 
[22]> c 
(42 2 3) 

लेकिन आप ऐसा नहीं कर सकते SETQ साथ:

[23]> (setq (car c) 42)            
*** - SETQ: (CAR C) is not a symbol 
The following restarts are available: 
USE-VALUE  :R1  Input a value to be used instead. 
ABORT   :R2  Abort main loop 
Break 1 [24]> abort 
+0

यदि एक चर जो मैं defvar द्वारा परिभाषित करता हूं, क्या मैं defparameter द्वारा मान बदल सकता हूं? क्या ऐसा करने का सही तरीका है? या defparameter में केवल परिवर्तनीय परिभाषित defparameter द्वारा बदला जा सकता है? धन्यवाद ~ – sam

+22

फ़ाइलों में मूल्य प्रारंभिकरण के लिए DEFVAR और DEFPARAMETER का उपयोग करने का सही तरीका है, श्रोता में गतिशील चर घोषित करने के लिए एक या दूसरे का उपयोग करें और हमेशा गैर-अपूर्ण कोड में मान बदलने के लिए SETF का उपयोग करें। DEFVAR और DEFPARAMETER के बीच का अंतर तब बन जाता है "क्या मैं इस फ़ाइल को लोड करते समय मूल्य को रीसेट करना चाहता हूं," (defparamete का उपयोग करें), "या नहीं?" (defvar का उपयोग करें)। – Vatine

22

defvar और defparameter दोनों एक "गतिशील रूप से स्कॉप्ड चर" के रूप में एक चर घोषित करेंगे। इसके अलावा, defparameter हमेशा वैरिएबल का मान दूसरे मान के रूप में आपके द्वारा पारित मूल्य पर सेट करेगा। यह defvar से अलग है, यह केवल चर के मान को सेट करेगा यदि यह पहले सेट नहीं किया गया है।

वैश्विक लेक्सिकल स्कोप में setf या setq के साथ एक चर परिभाषित करना अनिर्धारित है। कुछ कार्यान्वयन आपके लिए गतिशील रूप से स्कॉप्ड वैरिएबल बनाएंगे, कुछ नहीं करेंगे। जब आप पहली बार ऐसा करते हैं तो आप डायग्नोस्टिक संदेश देख सकते हैं।

lexically-दायरे वाले और गतिशील रूप-दायरे वाले चर के बीच के अंतर को समझने के लिए, कोशिश निम्नलिखित कोड का टुकड़ा:

* (defvar *a* 1) 

*A* 
* (let ((*a* 5)) (defun demo-a() *a*)) 

DEMO-A 
* (let ((b 5)) (defun demo-b() b)) 

DEMO-B 
* (let ((*a* 100)) (demo-a)) 

100 
* (let ((b 100)) (demo-b)) 

5 

यहाँ हम एक गतिशील-दायरे चर बना सकते हैं और एक समारोह है कि मूल्य (एक के अंदर परिभाषित वापसी बाध्यकारी जहां कार्य निर्माण के दौरान इसका एक अलग मूल्य है, यह जरूरी नहीं है और केवल बी पर लेक्सिकल क्लोजर के समान दिखने के लिए किया जाता है)। फिर हम एक नया चर परिभाषित करते हैं और एक फ़ंक्शन को अपना मान वापस परिभाषित करते हैं।

उसके बाद, हम दोनों कार्यों को कॉल करते हैं, एक ही नाम के एक चर के लिए मूल्य को बाध्य करने के अंदर। गतिशील स्कोपिंग मामले में, यह वही चर है। लेक्सिकल क्लोजर केस (बी) में, उनके पास केवल वही नाम है, लेकिन वे समान वैरिएबल नहीं हैं, क्योंकि उन्हें दो अलग-अलग शब्दावली बंद में परिभाषित किया गया है।

जहाँ तक setf और setq के बीच अंतर के रूप में, हमेशा setf उपयोग करने के लिए (मैं किसी भी उदाहरण है जहाँ (setq blah blahblah) काम करेगा और (setf blah blahblah) एक ही बात नहीं करते नहीं सोच सकते हैं) की कोशिश करो।

+0

अब मैं defvar और defparameter के बीच अंतर पता है। लेकिन जब मामला है तो हमें setf या setq का उपयोग करना चाहिए? धन्यवाद ~ – sam

+6

@ एसएएम: 'defvar',' defparameter', या 'let' का उपयोग नए चर को पेश करने के लिए करें। मौजूदा चर को म्यूटेट करने के लिए 'setf' और' setq' का उपयोग करें।नए चर को पेश करने के लिए उनका उपयोग करना अनिर्धारित व्यवहार है। –

+0

अंतिम उदाहरण (चलो ((बी 100)) (डेमो-बी)) मुझे 100 भी देता है, 5 नहीं दिखाया गया है जैसा कि –

संबंधित मुद्दे