Menu
Coddy logo textTech
flag Ar iconالعربيةdown icon

From و Into

جزء من قسم Object Oriented Programming في رحلة 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() تعليقاً توضيحياً للنوع (type annotation) لأن لغة Rust تحتاج إلى معرفة النوع الذي تقوم بالتحويل إليه. هذا النمط مفيد بشكل خاص عندما يكون لديك هياكل مساعدة (helper structs) تحتاج إلى تحويلها إلى أنواعك الأساسية - مثل تحويل بيانات التكوين (configuration data) إلى كائن مهيأ، أو تحويل المدخلات الخام إلى هيكل تم التحقق من صحته.

challenge icon

التحدي

سهل

لنقم ببناء نظام لتحويل درجات الحرارة باستخدام سمة From! ستقوم بإنشاء نوعين لدرجة الحرارة—Celsius و Fahrenheit—وتنفيذ التحويلات بينهما باستخدام سمات التحويل القياسية في Rust.

ستقوم بتنظيم الكود الخاص بك عبر ملفين:

  • temperature.rs: قم بتعريف هيكلين عامين من نوع newtype—وهما Celsius و Fahrenheit—كلاهما يغلف نوع f64. قم بتنفيذ سمة From لتحويل Celsius إلى Fahrenheit باستخدام الصيغة: fahrenheit = celsius × 1.8 + 32.0. أضف أيضاً طريقة value لكل هيكل تعيد قيمة f64 الداخلية.
  • main.rs: قم باستيراد وحدة درجة الحرارة الخاصة بك واستعرض كلا طريقتي التحويل. أنشئ قيمة Celsius من المدخلات المقدمة، ثم حولها إلى Fahrenheit باستخدام Fahrenheit::from(). أنشئ قيمة Celsius أخرى وقم بتحويلها باستخدام طريقة .into(). اطبع كلتا النتيجتين.

صيغة التحويل من Celsius إلى Fahrenheit هي: اضرب في 1.8 وأضف 32. تذكر أن تنفيذ From<Celsius> for Fahrenheit يمنحك تلقائياً سمة Into<Fahrenheit> على Celsius مجاناً!

يجب أن يعرض مخرجك كلا التحويلين بهذا التنسيق:

From: {celsius1}C = {fahrenheit1}F
Into: {celsius2}C = {fahrenheit2}F

على سبيل المثال، مع المدخلات 0 و 100:

From: 0C = 32F
Into: 100C = 212F

ومع المدخلات 25 و -40:

From: 25C = 77F
Into: -40C = -40F

ستتلقى مدخلين: قيمة Celsius الأولى (قم بتحليلها كـ f64) وقيمة Celsius الثانية (قم بتحليلها كـ f64).

ورقة مرجعية

توفر سمة 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);

// Using From explicitly
let m1 = Meters::from(distance);

// Using Into (requires type annotation)
let distance = Kilometers(3.0);
let m2: Meters = distance.into();

تتطلب طريقة into() توضيحاً للنوع (type annotation) حتى تعرف لغة Rust النوع الذي تقوم بالتحويل إليه.

جرّب بنفسك

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: celsius1 من Celsius قم بإنشاء قيمة
    // TODO: Fahrenheit::from() باستخدام Fahrenheit قم بتحويلها إلى
    
    // TODO: celsius2 من Celsius قم بإنشاء قيمة أخرى
    // TODO: .into() باستخدام Fahrenheit قم بتحويلها إلى
    
    // TODO: :اطبع النتائج بالتنسيق التالي
    // From: {celsius1}C = {fahrenheit1}F
    // Into: {celsius2}C = {fahrenheit2}F
}
quiz iconاختبر نفسك

يتضمن هذا الدرس اختبارًا قصيرًا. ابدأ الدرس للإجابة عليه وتتبّع تقدمك.

جميع دروس Object Oriented Programming