ال

الدوال في Rust

1 تمرين

نبذة عن الدوال

الدوال أجسام من الكود تحتوي على عبارة أو تعبير واحد أو أكثر. ويمكن للدالة اختياريًا أن تُرجع قيمة.

يتبع أسلوب Rust حالة الثعبان في تسمية الدوال، حيث يُسبق تعريف الدالة بالكلمة المفتاحية fn. على سبيل المثال

fn do_nothing() {}

تحيط الأقواس الهلالية بصفر أو أكثر من المعاملات، مفصولة بفواصل. والمعامل هو ارتباط بقيمة من نوع معيّن تُمرَّر إلى الدالة. وحتى إن لم توجد معاملات، تظل الأقواس الهلالية مطلوبة في تعريف الدالة. وتُسمّى القيمة الفعلية التي تُمرَّر إلى معامل وسيطًا.

وتُعرف مجموعة المعاملات وقيمة الإرجاع بتوقيع الدالة. ويشترط توقيع الدالة تحديد نوع كل معامل.

وتحيط الأقواس المعقوفة بجسم الدالة: عباراتها وتعبيراتها. وحتى لو لم تحتوِ الدالة على أي عبارات أو تعبيرات، تظل الأقواس المعقوفة مطلوبة في تعريف الدالة.

في المثال التالي تأخذ الدالة معاملًا واحدًا من النوع i32، وتربطه بالاسم value، وتطبعه.

fn print_integer(value: i32) {
    println!("{value:?}");
}

لاحظ تعريف المعامل. يُعرَّف كل معامل بالصيغة name: Type.

ويمكن للدالة أيضًا أن تُرجع قيمة. وبشكل افتراضي، تُرجع الدالة ناتج التعبير الأخير. في المثال التالي للدالة معامل واحد من النوع i32 وتُرجع ضعفه.

fn double_integer(value: i32) -> i32 {
    value * 2
}

تشير -> i32 إلى أن الدالة تُرجع قيمة من النوع i32. وعلى عكس المعاملات، لا يكون للقيمة المُرجَعة اسم.

ويمكن الخروج من الدالة مبكرًا باستخدام الكلمة المفتاحية return، هكذا:

fn long_function() -> i32 {
    let some_condition = false;
    // code snipped
    if (some_condition) {
        return 0;
    }
    // more code snipped
    42
}

تُستخدم const fn لتعريف دالة ثابتة، يمكن تقييمها في وقت التصريف.

const fn compute_data_checksum() -> u128 {
  const DATA: &[u8] = include_bytes!("my_big_data_file");
  // checksum implementation is left as an exercise for the reader
}

/// This checksum is used to validate that the user has not tampered with proprietary configuration.
pub const DATA_CHECKSUM: u128 = compute_data_checksum();

ولأنه يمكن تقييم الدوال الثابتة في وقت التصريف، فإن لها بعض القيود التي لا توجد في الدوال العادية. على وجه الخصوص، لا يمكن لـ const fn أن تستدعي إلا دوالًا أخرى موسومة أيضًا بـ const. ومخالفة هذا القيد تؤدي إلى خطأ في التصريف.

const fn multiply_integer(value: i32) -> i32 {
    use std::time::SystemTime;
    if SystemTime::now().elapsed().unwrap().as_nanos() == 0 { // this line errors
        value * 2
    } else {
        value * 3
    }
}

وهناك دوال مجهولة، وهي مشروحة في موضوع closures.

تعديل عبر GitHub يفتح الرابط في نافذة أو علامة تبويب جديدة