سؤال

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

f <- function(x) {x+1}
a <- 1
f(a)

يكون a يتم تمريره حرفيًا أم إشارة إلى تمريره؟

x <- 1
y <- x

مرجع النسخة؟متى لا يكون هذا هو الحال؟

إذا كان شخص ما يمكن أن يشرح لي هذا سأكون ممتنا للغاية.

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

المحلول

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

?force
?delayedAssign

أحد الآثار العملية هو أنه من الصعب جدًا، إن لم يكن من المستحيل، تجنب الحاجة إلى ضعف ذاكرة الوصول العشوائي (RAM) التي تشغلها كائناتك اسميًا على الأقل.يتطلب تعديل كائن كبير عمومًا عمل نسخة مؤقتة.

تحديث:2015:أنا أتفق (ولقد اتفقت) مع Matt Dowle على أن حزمة data.table الخاصة به توفر طريقًا بديلاً للمهمة يتجنب مشكلة النسخ المكرر.إذا كان هذا هو التحديث المطلوب، فأنا لم أفهمه في وقت تقديم الاقتراح.

كان هناك تغيير حديث في R 3.2.1 في قواعد التقييم لـ apply و Reduce.تم الإعلان عن ذلك بالإشارة إلى الأخبار هنا: إرجاع وظائف مجهولة من لابلي - ما الخطأ الذي يحدث؟

و ال ورقة مثيرة للاهتمام استشهد بها jhetzel في التعليقات موجودة الآن هنا:

نصائح أخرى

إجابة متأخرة ولكنها جانب مهم جدًا من تصميم اللغة ولا تحظى بتغطية كافية على الويب (أو على الأقل المصادر المعتادة).

x <- c(0,4,2)
lobstr::obj_addr(x)
# [1] "0x7ff25e82b0f8"
y <- x
lobstr::obj_addr(y)
# [1] "0x7ff25e82b0f8"

لاحظ "عنوان الذاكرة" المتطابق، أي:الموقع في الذاكرة حيث يتم تخزين الكائن.وبذلك يمكنك تأكيد ذلك x و y كلاهما يشير إلى نفس المعرف.

يتطرق كتاب هادلي ويكهام Advanced R إلى هذا:

النظر في هذا الرمز:

x <- c(1, 2, 3)

من السهل قراءتها على النحو التالي:"قم بإنشاء كائن يسمى" X "، يحتوي على القيم 1 و 2 و 3".لسوء الحظ ، هذا تبسيط سيؤدي إلى تنبؤات غير دقيقة حول ما تفعله R بالفعل وراء الكواليس.من الأكثر دقة أن نقول إن هذا الرمز يقوم بأمرين:

إنه إنشاء كائن، ناقل للقيم، c(1, 2, 3).وهي ملزمة لهذا الكائن بالاسم ، x.بمعنى آخر ، لا يحتوي الكائن أو القيمة ، على اسم ؛إنه في الواقع الاسم الذي له قيمة.

لاحظ أن عناوين الذاكرة سريعة الزوال وتتغير مع كل جلسة R جديدة.

الآن هنا هو الجزء المهم.

في دلالات R، يتم نسخ الكائنات حسب القيمة.هذا يعني أن تعديل النسخة يترك الكائن الأصلي سليما.نظرًا لأن نسخ البيانات في الذاكرة هي عملية باهظة الثمن ، فإن النسخ في R كسول قدر الإمكان.تحدث فقط عندما يتم تعديل الكائن الجديد فعليًا.مصدر:[توثيق لغة R][1]

لذلك إذا قمنا الآن بتعديل قيمة y عن طريق إلحاق قيمة بالمتجه، y يشير الآن إلى "كائن" مختلف.يتوافق هذا مع ما تقوله الوثائق فيما يتعلق بعملية النسخ التي تحدث "فقط عند تعديل الكائن الجديد" (كسول). y يشير إلى عنوان مختلف عما كان عليه سابقًا.

y <- c(y, -3)
print(lobstr::obj_addr(y))
# [1] "0x7ff25e825b48"
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top