الدوال المرتبطة
جزء من قسم Object Oriented Programming في رحلة Rust على Coddy — الدرس 4 من 61.
ليست كل الدوال في كتلة impl تحتاج إلى العمل على مثيل موجود. الدوال التي لا تأخذ self كمعامل تُسمى دوالاً مرتبطة—فهي مرتبطة بالنوع نفسه بدلاً من أي مثيل معين.
الاستخدام الأكثر شيوعاً للدوال المرتبطة (associated functions) هو إنشاء المنشئات (constructors). وبناءً على العرف، غالباً ما تُسمى هذه الدوال بـ new:
struct Player {
name: String,
score: u32,
}
impl Player {
fn new(name: String) -> Player {
Player {
name,
score: 0,
}
}
}
لاحظ أنه لا يوجد معامل self—هذه الدالة لا تحتاج إلى Player موجود لكي تعمل. بدلاً من ذلك، فهي تقوم بإنشاء وإرجاع واحد جديد تماماً. نوع الإرجاع هو الـ struct نفسه.
لاستدعاء دالة مرتبطة، استخدم بناء الجملة :: مع اسم النوع بدلاً من تدوين النقطة:
fn main() {
let player1 = Player::new(String::from("Alice"));
println!("{} starts with {} points", player1.name, player1.score);
// المخرجات: تبدأ Alice بـ 0 نقاط
}
يوفر هذا النمط طريقة نظيفة لتهيئة الـ structs بقيم افتراضية أو منطق تحقق، مما يحافظ على منطق الإنشاء مدمجاً مع تعريف النوع. من المحتمل أنك رأيت هذا النحو بالفعل مع String::from()—هذه دالة مرتبطة (associated function) أيضاً!
التحدي
سهلقم بإنشاء هيكل Book يحتوي على حقلين: title (String) و pages (u32).
أضف كتلة تنفيذ (implementation block) لـ Book تحتوي على دالة مرتبطة (associated function) تسمى new تقوم بما يلي:
- تستقبل معامل
title: String - تعيد كائن
Bookجديد بالعنوان المعطى مع تعيينpagesإلى0
أضف أيضاً طريقة (method) تسمى info تأخذ &self وتعيد String بالتنسيق التالي: "{title} has {pages} pages"
ستتلقى مدخلاً واحداً:
- عنوان الكتاب (String)
استخدم الدالة المرتبطة Book::new لإنشاء كتاب بالعنوان المقدم، ثم اطبع نتيجة استدعاء طريقة info.
تنسيق المخرجات المتوقع:
{title} has {pages} pagesورقة مرجعية
تُسمى الدوال الموجودة في كتلة impl والتي لا تأخذ self كمعامل بـ الدوال المرتبطة (associated functions). فهي ترتبط بالنوع نفسه بدلاً من أي مثيل (instance) محدد.
تُستخدم الدوال المرتبطة بشكل شائع كمنشئات (constructors)، وعادةً ما تُسمى new:
struct Player {
name: String,
score: u32,
}
impl Player {
fn new(name: String) -> Player {
Player {
name,
score: 0,
}
}
}
لاستدعاء دالة مرتبطة، استخدم صيغة :: مع اسم النوع:
let player1 = Player::new(String::from("Alice"));
تُعد String::from() مثالاً على دالة مرتبطة قمت باستخدامها بالفعل.
جرّب بنفسك
use std::io;
// TODO: (String) وحقول الصفحات (u32) title قم بتعريف هيكل الكتاب مع حقول العنوان
// TODO: مع ما يلي: Book أضف كتلة تنفيذ لهيكل
// - دالة مرتبطة `new` تأخذ عنواناً وتعيد كتاباً مع تعيين عدد الصفحات إلى 0
// - طريقة `info` تعيد سلسلة نصية بتنسيق "{title} has {pages} pages"
fn main() {
let mut input = String::new();
io::stdin().read_line(&mut input).expect("Failed to read line");
let title = input.trim().to_string();
// TODO: لإنشاء كتاب بالعنوان المقدم Book::new استخدم
// TODO: info اطبع نتيجة استدعاء طريقة
}يتضمن هذا الدرس اختبارًا قصيرًا. ابدأ الدرس للإجابة عليه وتتبّع تقدمك.
جميع دروس Object Oriented Programming
1الأساليب والسلوك
مقدمة في كتل التنفيذمعامل Selfالأساليب القابلة للتعديلالدوال المرتبطةكتل تنفيذ متعددةتسلسل الأساليبمراجعة - إجراءات المستطيل4مشروع: حيوان أليف افتراضي
تعريف الحيوان الأليفإطعام الحيوان الأليف2التغليف والوحدات البرمجية
أساسيات الوحدات البرمجيةالكلمة المفتاحية Publicالحقول الخاصةدوال Gettersدوال Settersمراجعة - الخزانة الآمنة5الأنواع العامة (Generics)
الـ Structs العامةالـ Methods العامةأنواع عامة متعددةالـ Functions العامةمراجعة - Coordinate Point3التعدادات المتقدمة (Advanced Enums)
التعدادات مع البياناتالأساليب (Methods) في التعداداتمطابقة حالات البياناتمراجعة التعداد Optionملخص - التعداد Shape6تعريف الـ Traits
ما هي الـ Trait؟تنفيذ الـ Traitsالتنفيذات الافتراضيةتجاوز التنفيذات الافتراضيةالـ Traits مع المعاملاتملخص - مشغل الوسائط