2011-01-08 16 views
5

कोड नीचे z एक स्थानीय चर के रूप में है, फिर भी यह बर्ताव करता है जैसे कि यह एक वैश्विक है:सामान्य लिस्प में संपत्ति सूचियां कुछ वैश्विक राज्यों का संदर्भ लें?

(defun foo (m) 
    (let ((z '(stuff nil))) 
    (push m (getf z 'stuff)) 
    (print z))) 

(foo 1) 
(foo 2) 
(foo 3) 

मैं उत्पादन

(STUFF (1)) 
(STUFF (2)) 
(STUFF (3)) 
T 

होने की अपेक्षा करेंगे लेकिन जब यह SBCL मैं के साथ चल रहा देखें

(STUFF (1)) 
(STUFF (2 1)) 
(STUFF (3 2 1)) 
T 

ऐसा क्यों है? क्या यह व्यवहार संपत्ति सूचियों के लिए विशिष्ट है?

+0

[डेटा का अप्रत्याशित हठ] (के संभावित डुप्लिकेट http://stackoverflow.com/questions/187901 9 2/अप्रत्याशित-स्थिरता-डेटा) –

उत्तर

6

foo, z शाब्दिक अभिव्यक्ति '(stuff nil) से जुड़ा हुआ है। कार्य विनाशकारी रूप से z बदलता है, इस प्रकार शाब्दिक रूप से विनाशकारी रूप से मूल्य बदल रहा है। एलआईएसपी इस तरह की परिस्थितियों में कैसे व्यवहार करता है कार्यान्वयन-निर्भर है। कुछ कार्यान्वयन आज्ञाकारी रूप से शाब्दिक मूल्य (आपके मामले में) को बदल देंगे। अन्य कार्यान्वयन केवल पढ़ने योग्य स्मृति स्थानों में अक्षर लेते हैं और यदि आप उन अक्षरों को संशोधित करने का प्रयास करते हैं तो विफल हो जाएंगे।

वांछित व्यवहार पाने के लिए, COPY-LIST का उपयोग शाब्दिक की एक प्रति है कि सुरक्षित रूप से संशोधित किया जा सकता बनाने के लिए:

(defun foo (m) 
    (let ((z (copy-list '(stuff nil)))) 
    (push m (getf z 'stuff)) 
    (print z))) 
+7

मुझे लगता है कि 'LIST' का उपयोग करना अधिक मूर्खतापूर्ण तरीका होगा, जैसा कि' (चलो ((z (सूची 'सामान शून्य)) ...) ' – Ken