غالبًا ما يكون من المفيد تجميع مجموعة من العناصر معًا والتعامل مع هذه المجموعات كوحدات كاملة. في Rust نسمي هذه المجموعة بنية، ونسمي كل عنصر فيها أحد حقول البنية. تحدد البنية المجموعة العامة من الحقول المتاحة، أما المثال المعيّن منها فيسمى نسخة.
كذلك يمكن تعريف طرق على البنى، وهذه الطرق لها وصول إلى الحقول. وفي هذه الحالة يُشار إلى البنية نفسها باسم self. وعندما تستخدم طريقة &mut self، يمكن تغيير الحقول، أي تعديلها. أما عندما تستخدم طريقة &self، فلا يمكن تغيير الحقول: فهي غير قابلة للتغيير. ويساعد التحكم في قابلية التغيير مدقّق الاقتراض على ضمان ألا تحدث في Rust فئات كاملة من أخطاء التزامن على الإطلاق.
في هذا التمرين، ستُنفّذ نوعين من الطرق على بنية. تُعرف الطرق من النوع الأول عمومًا باسم دوال الجلب: فهي تكشف حقول البنية للعالم الخارجي، دون أن تسمح لأي طرف آخر بتغيير تلك القيمة. وفي Rust، تحمل هذه الطرق عادةً اسم الحقل الذي تكشفه، أي إن كانت لدينا طريقة جلب تُحضر حقلًا في البنية اسمه name، فستكون الطريقة ببساطة باسم name().
ستنفّذ أيضًا طرقًا من نوع آخر تُعرف عمومًا باسم دوال الضبط. وهذه تغيّر قيمة الحقل. ولا تنتشر دوال الضبط كثيرًا في Rust: فإذا كان الحقل قابلًا للتعديل بحرية، فالأكثر شيوعًا هو جعله عامًا، لكنها مفيدة إذا كان تحديث الحقل ينبغي أن يُحدث آثارًا جانبية، أو لأغراض التحكم في الوصول: فدالة ضبط معلَّمة بـ pub(crate) تسمح لوحدات أخرى داخل crate نفسه بتحديث حقل خاص لا يمكن للعالم الخارجي التأثير فيه.
تأتي البنى بثلاث صور: بنى ذات حقول مسماة، وبنى الصف، وبنى الوحدة. وفي تمرين المفهوم هذا، سنستكشف الصورة الأولى: البنى ذات الحقول المسماة.
تُعرَّف البنى باستخدام الكلمة المفتاحية struct، متبوعة باسم النوع الذي تصفه البنية مبدوءًا بحرف كبير:
struct Item {}
ثم تُضاف أنواع أخرى إلى جسم البنية بوصفها حقولًا لها، ولكل منها نوعها الخاص:
struct Item {
name: String,
weight: f32,
worth: u32,
}
وأخيرًا، يمكن تعريف طرق على البنى داخل كتلة impl:
impl Item {
// initializes and returns a new instance of our Item struct
fn new() -> Self {
todo!()
}
}
وبعد هذه المقدمة الموجزة عن صياغة البنى، تفضّل بإلقاء نظرة على التعليمات الخاصة بهذا التمرين!
أنت تعمل على تنفيذ نظام لمراقبة الصحة. وكجزء من ذلك، تحتاج إلى تتبّع الإحصاءات الصحية للمستخدمين.
ستبدأ ببعض الدوال غير المُنفَّذة في كتلة impl بالإضافة إلى تعريف struct التالي:
pub struct User {
name: String,
age: u32,
weight: f32,
}
هدفك هو تنفيذ الطرق غير المُنفَّذة على struct المسمّى User والمعرَّف في كتلة impl.
على سبيل المثال، يجب أن تُرجع الطريقة new نسخة من struct المسمّى User بالقيم المحدَّدة للاسم والعمر والوزن.
let mut bob = User::new(String::from("Bob"), 32, 155.2);
// Returns: a User with name "Bob", age 32, and weight 155.2
يجب أن تُرجع الطريقة weight وزن User.
bob.weight();
// Returns: 155.2
يجب أن تضبط الطريقة set_age عمر User.
bob.set_age(33);
// Updates Bob's age to 33; happy birthday Bob!
استمتع بوقتك!
سجّل في Exercism لتتعلّم وتتقن Rust عبر 99 تمرينًا، وإرشاد بشري حقيقي، وكل ذلك مجانًا.