Rust / دليل حلول تحريري
حل E0382: استخدام قيمة منقولة
حدّد انتقال الملكية واختر الاستعارة أو الاستهلاك وافحص تدفق البيانات دون استنساخ تلقائي.
قاعدة معرفة للقراءة فقط · بلا تعليقات عامة
تعرّف على الأعراض
يبلغ المترجم عن E0382 عند استعمال قيمة بعد نقلها. يشير التشخيص عادة إلى النقل والاستعمال اللاحق. هذا رفض ترجمة لا تعطل تنفيذ ولا توقع لطباعة String فارغة. لا يُنسب إلى البرنامج المرفوض إخراج تنفيذي.
قد يظهر بعد إسناد أو استدعاء مستهلك أو تكرار مملوك أو تفكيك نمط أو نقل بيانات من إغلاق. حدّد العملية بدل افتراض صحة كل اقتراح مرجع أو استنساخ.
افهم الأسباب المحتملة
- ليستا String وVec من Copy. ينقل إسنادهما أو تمريرهما بالقيمة الملكية عادة فيبطل استخدام الارتباط القديم كقيمة كاملة. تتيح mut التعديل ولا تبيح إعادة المنقول. وقد يقيد النقل الجزئي تجميعة مع بقاء حقول أخرى.
- يقول معامل String إنه يستقبل ملكية، وقد يتجاوز حاجة المراقبة فقط. يختلف نسخ العدد لدعم نوعه Copy. وتختلف Clone حسب النوع؛ تنشئ String نصًا مستقلًا وتشارك Rc وArc التخصيص نفسه.
تحديد النقل قبل تعديل الشيفرة
اتبع موقع التشخيص من الارتباط إلى الاستهلاك ثم الاستخدام. يمرر المقتطف المرفوض String إلى consume ثم يحاول طباعتها، ولا تعيد الدالة الملكية. لا تصلح mut العقد. أبقِ المثال غير قابل للتشغيل واستخدم فحص المترجم لا التنفيذ.
fn consume(text: String) -> usize { text.len() }
fn main() {
let text = String::from("note");
let _length = consume(text);
println!("{text}");
}
مرفوض عمدًا برمز E0382 ولا يُنسب إليه إخراج.
الاستعارة للمراقبة فقط
غيّر المعامل إلى &str عند القراءة المؤقتة. يستعير التصحيح String ويعيد عدد بايتات مستقلًا. يحتفظ المستدعي بالملكية ويطبع الأصل بعده. تقبل &str النصوص الحرفية والشرائح أيضًا فتطلب ملكية أقل. هذا إصلاح دلالي لا حيلة لإخفاء الخطأ.
fn byte_count(text: &str) -> usize { text.len() }
fn main() {
let text = String::from("note");
let length = byte_count(&text);
println!("{text} {length}");
}
note 4
تبقى String ملك main وتستعيرها الدالة أثناء الاستدعاء فقط وتعيد أربعة بايتات.
إبقاء الاستهلاك عند حاجة الملكية
إذا خزنت الدالة السلسلة أو أرسلتها لعامل فقد يصح استلام الملكية. توقف عن استخدام القديم أو أعد الملكية صراحة أو استنسخ قبل النقل لحاجة استقلال حقيقية. اختر iter للمراقبة وinto_iter المملوكة للاستهلاك. لا تفرض Clone على واجهة كاملة لتسهيل استدعاء واحد؛ فذلك يغير الكلفة والأنواع لكل المستهلكين.
تحقق من نجاح الإصلاح
ترجم المثال المصحح باستخدام Rust 1.85 أو أحدث و--edition=2024. يجب أن يطبع note 4 ثم سطرًا جديدًا. أبقِ استخدام المستدعي بعد دالة المراقبة ليحمي الاختبار العقد المصحح فعلًا.
استخدم rustc --explain E0382 للخلفية الرسمية واختبارات رفض الترجمة إن دعمها المشروع. لا تنفذ المقتطف الفاسد. وافحص استقلال البيانات إذا كان ذلك سبب استخدام clone.
امنع تكرار المشكلة
- اقرأ ملكية المعاملات والمكررات قبل الاستدعاء، ووثّق احتفاظ الردود بالبيانات وميّز استنساخ المقبض من اللقطة المستقلة. اختر أقل نقل يحقق العمر الفعلي.