سؤال

هذا المقطع من On Lisp ليس من الواضح كيف يعود قائمة نقلت مثل '(oh my) يمكن أن يغير في الواقع كيف تتصرف الوظيفة في المستقبل:لن يتم إنشاء قائمة عاد مرة أخرى في وظيفة من الصفر, في المرة القادمة يطلق عليه?

إذا حددنا هتف بحيث قيمة عودتها يتضمن قائمة مقتبسة,

(defun exclaim (expression) 
  (append expression ’(oh my)))

ثم أي تعديل مدمر لاحق لقيمة الإرجاع

(exclaim ’(lions and tigers and bears)) 
->  (LIONS AND TIGERS AND BEARS OH MY)
(nconc * ’(goodness))
->  (LIONS AND TIGERS AND BEARS OH MY GOODNESS)

يمكن أن يغير القائمة داخل الوظيفة:

(exclaim ’(fixnums and bignums and floats)) 
->  (FIXNUMS AND BIGNUMS AND FLOATS OH MY GOODNESS)

لجعل دليل هتف ضد مثل هذه المشاكل ، ينبغي أن تكون مكتوبة:

(defun exclaim (expression)
  (append expression (list ’oh ’my)))

كيف بالضبط هو أن الدعوة الأخيرة ل exclaim إضافة الكلمة goodness إلى النتيجة?لا تشير الوظيفة إلى أي متغير خارجي ، فكيف فعلت المكالمة المنفصلة إلى nconc في الواقع تغيير كيفية exclaim يعمل وظيفة?

هل كانت مفيدة؟

المحلول

أ) آثار التعديل حرفي القوائم غير محددة في معيار اللثغة المشترك.ما تراه هنا كمثال هو سلوك واحد ممكن.

(1 2 3 4) هي قائمة حرفية.لكن دعوة إلى LIST مثل في (list 1 2 3 4) إرجاع قائمة جديدة في وقت التشغيل.

ب) القائمة هي بيانات حرفية في رمز الوظيفة.ستعيد كل مكالمة كائن البيانات هذا بالضبط.إذا كنت ترغب في تقديم قائمة جديدة في كل مكالمة ، فأنت بحاجة إلى استخدام شيء مثل القائمة أو قائمة النسخ.

ج) نظرا لأن القائمة التي تم إرجاعها هي دائما نفس كائن البيانات الحرفي ، فإن تعديلها يمكن أن يكون له هذا التأثير كما هو موضح.يمكن للمرء أن يتصور أيضا أن خطأ يحدث إذا تم تخصيص التعليمات البرمجية وكائناتها في ذاكرة للقراءة فقط.تعديل القائمة ثم محاولة الكتابة إلى الذاكرة للقراءة فقط.

د) شيء واحد يجب أخذه في الاعتبار عند العمل مع بيانات القائمة الحرفية في شفرة المصدر هو هذا:مترجم ليسب مجاني لتحسين التخزين.إذا حدث أن تكون القائمة عدة مرات في التعليمات البرمجية المصدر ، يسمح للمترجم باكتشاف ذلك وإنشاء قائمة واحدة فقط.ثم تشير جميع الأماكن المختلفة إلى هذه القائمة الواحدة.وبالتالي فإن تعديل القائمة سيكون له تأثير ، أن هذه التغييرات يمكن أن تكون مرئية في عدة أماكن.

قد يحدث هذا أيضا مع كائنات البيانات الحرفية الأخرى مثل المصفوفات/المتجهات.

إذا كانت بنية البيانات الخاصة بك جزءا من التعليمات البرمجية ، يمكنك إرجاع بنية البيانات الداخلية هذه ، يمكنك تعديل بنية البيانات هذه - ثم تحاول تعديل التعليمات البرمجية الخاصة بك.

لاحظ أيضا أن ليسب يمكن تنفيذها من قبل مترجم.المترجم يعمل عادة على هيكل مصدر ليسب-رمز ليس رمز الجهاز ، ولكن تفسير رمز ليسب كما بيانات ليسب.هنا قد تكون قادرا على تعديل التعليمات البرمجية المصدر في وقت التشغيل ، وليس فقط البيانات المضمنة في التعليمات البرمجية المصدر.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top