From و Into
جزء من قسم البرمجة كائنية التوجه في رحلة Rust على Coddy. الدرس 57 من 61.
يُعدّ التحويل بين الأنواع مهمة شائعة في Rust. توفّر سمة From طريقةً موحّدة لتعريف كيفية إنشاء نوع من نوع آخر. عند تنفيذ From، تحصل تلقائيًا على سمة Into مجانًا.
لتنفيذ From، تعرّف كيفية إنشاء نوعك من نوع آخر:
struct Meters(f64);
struct Kilometers(f64);
impl From<Kilometers> for Meters {
fn from(km: Kilometers) -> Self {
Meters(km.0 * 1000.0)
}
}
يمكنك الآن إجراء التحويل باستخدام إما الدالة from أو الطريقة into:
let distance = Kilometers(5.0);
// استخدام From بشكل صريح
let m1 = Meters::from(distance);
// استخدام Into (يعمل لأن From مُنفَّذ)
let distance = Kilometers(3.0);
let m2: Meters = distance.into();
تتطلب طريقة into() تعليقًا توضيحيًا للنوع، لأن Rust تحتاج إلى معرفة النوع الذي تُحوِّل إليه. يكون هذا النمط مفيدًا بشكل خاص عندما تكون لديك هياكل مساعدة تحتاج إلى تحويلها إلى الأنواع الرئيسية، مثل تحويل بيانات التكوين إلى كائن مُهيَّأ، أو تحويل input خام إلى بنية تم التحقق من صحتها.
التحدي
سهللنَبْنِ نظامًا لتحويل درجات الحرارة باستخدام سمة From! ستنشئ نوعين لدرجات الحرارة، Celsius وFahrenheit، وتنفّذ عمليات التحويل بينهما باستخدام سمات التحويل القياسية في Rust.
ستنظّم شيفرتك عبر ملفين:
temperature.rs: Define بنيتي newtype عامتين،CelsiusوFahrenheit، وكلتاهما تغلّفان قيمةf64. نفّذ سمةFromلتحويلCelsiusإلىFahrenheitباستخدام الصيغة:fahrenheit = celsius × 1.8 + 32.0. أضف أيضًا method باسمvalueإلى كل بنية، بحيث returns قيمةf64الداخلية.main.rs: استدعِ وحدة درجات الحرارة، واعرض طريقتَي التحويل. أنشئ قيمةCelsiusمن input المقدَّم، ثم حوّلها إلىFahrenheitباستخدامFahrenheit::from(). أنشئ قيمةCelsiusأخرى وحوّلها باستخدام method.into(). اطبع النتيجتين.
صيغة التحويل من Celsius إلى Fahrenheit هي: اضرب في 1.8 ثم أضف 32. Remember أن تنفيذ From<Celsius> for Fahrenheit يمنحك تلقائيًا سمة Into<Fahrenheit> على Celsius مجانًا!
تُطبع درجتا الحرارة كأعداد صحيحة: حوّل كل قيمة f64 باستخدام as i64، إذ يقتطع الكسور باتجاه الصفر. لذلك تُطبع قيمة input مقدارها 36.6 على شكل 36C، كما تُطبع درجة Fahrenheit البالغة 97.88 التي تتحول إليها على شكل 97F. لا يحدث أي تقريب إلى الأعلى.
يجب أن يعرض output كلا التحويلين بهذا التنسيق:
From: {celsius1}C = {fahrenheit1}F
Into: {celsius2}C = {fahrenheit2}Fعلى سبيل المثال، عند استخدام input بالقيمتين 0 و100:
From: 0C = 32F
Into: 100C = 212Fوعند استخدام input بالقيمتين 25 و-40:
From: 25C = 77F
Into: -40C = -40Fستتلقى inputين: قيمة Celsius الأولى (parse على أنها f64) وقيمة Celsius الثانية (parse على أنها f64).
جرّب بنفسك
mod temperature;
use temperature::{Celsius, Fahrenheit};
fn main() {
// اقرأ المدخلات
let mut input1 = String::new();
std::io::stdin().read_line(&mut input1).expect("Failed to read line");
let celsius1: f64 = input1.trim().parse().expect("Invalid number");
let mut input2 = String::new();
std::io::stdin().read_line(&mut input2).expect("Failed to read line");
let celsius2: f64 = input2.trim().parse().expect("Invalid number");
// TODO: أنشئ قيمة Celsius من celsius1
// TODO: حوّلها إلى Fahrenheit باستخدام Fahrenheit::from()
// TODO: أنشئ قيمة Celsius أخرى من celsius2
// TODO: حوّلها إلى Fahrenheit باستخدام .into()
// TODO: اطبع النتائج بالصيغة:
// From: {celsius1}C = {fahrenheit1}F
// Into: {celsius2}C = {fahrenheit2}F
}
يتضمن هذا الدرس اختبارًا قصيرًا. ابدأ الدرس للإجابة عليه وتتبّع تقدمك.
جميع دروس البرمجة كائنية التوجه
1الأساليب والسلوك
مقدمة في كتل التنفيذمعامل Selfالأساليب القابلة للتعديلالدوال المرتبطةكتل تنفيذ متعددةتسلسل الأساليبمراجعة - إجراءات المستطيل4مشروع: حيوان أليف افتراضي
تعريف الحيوان الأليفإطعام الحيوان الأليف2التغليف والوحدات البرمجية
أساسيات الوحدات البرمجيةالكلمة المفتاحية Publicالحقول الخاصةدوال Gettersدوال Settersمراجعة - الخزانة الآمنة5الأنواع العامة (Generics)
الـ Structs العامةالـ Methods العامةأنواع عامة متعددةالـ Functions العامةمراجعة - Coordinate Point3التعدادات المتقدمة (Advanced Enums)
التعدادات مع البياناتالأساليب (Methods) في التعداداتمطابقة حالات البياناتمراجعة التعداد Optionملخص - التعداد Shape6تعريف الـ Traits
ما هي الـ Trait؟تنفيذ الـ Traitsالتنفيذات الافتراضيةتجاوز التنفيذات الافتراضيةالـ Traits مع المعاملاتملخص - مشغل الوسائطتدرّب بنفسك: مترجم Rust عبر الإنترنت