الـ Traits مع المعاملات
جزء من قسم البرمجة كائنية التوجه في رحلة Rust على Coddy. الدرس 33 من 61.
حتى الآن، لم تتلقَّ trait methods لدينا سوى &self كمعامل. لكن يمكن لـ trait methods قبول معاملات إضافية تمامًا مثل methods العادية. وهذا يجعلها أكثر فائدة بكثير للعمليات في العالم الحقيقي.
عند تعريف trait، يمكنك تضمين أي معلمات تحتاج إليها في توقيعات الأساليب:
trait Calculator {
fn add(&self, a: i32, b: i32) -> i32;
fn multiply(&self, a: i32, b: i32) -> i32;
}
يتطلب هذا Calculator trait وجود طريقتين، تقبل كل منهما عددين صحيحين بالإضافة إلى &self. يجب على أي نوع يطبّق هذا trait توفير العمليتين بالتوقيعات نفسها تمامًا.
إليك كيفية تنفيذ بنية له:
struct BasicCalc;
impl Calculator for BasicCalc {
fn add(&self, a: i32, b: i32) -> i32 {
a + b
}
fn multiply(&self, a: i32, b: i32) -> i32 {
a * b
}
}
يمكنك الآن استخدام هذه methods مع الوسائط:
let calc = BasicCalc;
println!("{}", calc.add(5, 3)); // 8
println!("{}", calc.multiply(4, 7)); // 28
تحدّد السمة ما المعلمات التي يقبلها كل method، بينما يحدّد التنفيذ كيفية استخدام تلك المعلمات. يتيح هذا للأنواع المختلفة تنفيذ العمليات نفسها بطريقتها الخاصة: فربما يطبع LoggingCalc كل عملية قبل إرجاع result.
التحدي
سهللنَبْنِ مجموعة أدوات لمعالجة السلاسل النصية، حيث يمكن لمعالجات مختلفة تحويل النص بطرقها الخاصة! ستنشئ سمة TextProcessor تحتوي على methods تقبل parameters، ثم ستطبّقها على نوعين مختلفين من المعالجات.
ستنظّم كودك عبر ثلاثة ملفات:
processor.rs: عرّف سمةTextProcessorعامة تحتوي على methodين يقبلان parameters:repeat(&self, text: &str, times: u32) -> String: تكرّر النص المعطى عددًا محددًا من المراتtruncate(&self, text: &str, max_len: usize) -> String: تختصر النص إلى الحد الأقصى المحدد للطول
processors.rs: أنشئ structين عامين يطبّقان السمة:SimpleProcessor: struct وحدوي يكرّر النص مع وضع مسافات بين كل تكرار (مثلًا، يصبح "Hi" المكرّر 3 مرات "Hi Hi Hi") ويختصره ببساطة عبر القطع عند الحد الأقصى للطولFancyProcessor: struct وحدوي يكرّر النص مع وضع " * " بين التكرارات (مثلًا، يصبح "Hi" المكرّر 3 مرات "Hi * Hi * Hi") ويختصره بإضافة "..." إذا تم اختصار النص (فقط إذا كان النص الأصلي أطول من max_len)
main.rs: اجمع modules معًا ووضّح كيف تنتج methods السمة نفسها results مختلفة بناءً على processor الذي تستخدمه.
في ملفك الرئيسي، أنشئ كلا processorين واستخدم inputs لاختبارهما. ستتلقى ثلاثة inputs: سلسلة نصية، وعدد مرات التكرار، وطولًا أقصى.
اطبع أربعة أسطر توضّح سلوك كل processor:
Simple repeat: {result}
Simple truncate: {result}
Fancy repeat: {result}
Fancy truncate: {result}على سبيل المثال، عند استخدام inputs Hello و3 و4:
Simple repeat: Hello Hello Hello
Simple truncate: Hell
Fancy repeat: Hello * Hello * Hello
Fancy truncate: Hell...لاحظ كيف يفي كلا processorين بعقد TextProcessor نفسها، لكن كلًّا منهما يحوّل النص بطريقته الفريدة! تحدد السمة ما هي parameters التي تقبلها methods، بينما يقرر كل implementation كيفية استخدامها!
ستتلقى ثلاثة inputs: النص المراد معالجته، وعدد التكرارات (حلّله كـ u32)، والحد الأقصى للطول من أجل الاختصار (حلّله كـ usize).
جرّب بنفسك
mod processor;
mod processors;
use processor::TextProcessor;
use processors::{SimpleProcessor, FancyProcessor};
fn main() {
// قراءة المدخلات
let mut text = String::new();
std::io::stdin().read_line(&mut text).expect("Failed to read line");
let text = text.trim();
let mut times_input = String::new();
std::io::stdin().read_line(&mut times_input).expect("Failed to read line");
let times: u32 = times_input.trim().parse().expect("Failed to parse times");
let mut max_len_input = String::new();
std::io::stdin().read_line(&mut max_len_input).expect("Failed to read line");
let max_len: usize = max_len_input.trim().parse().expect("Failed to parse max_len");
// إنشاء المعالجات
let simple = SimpleProcessor;
let fancy = FancyProcessor;
// TODO: استخدم المعالجات لتحويل النص وطباعة النتائج
// اطبع أربعة أسطر:
// Simple repeat: {result}
// Simple truncate: {result}
// Fancy repeat: {result}
// Fancy truncate: {result}
}
يتضمن هذا الدرس اختبارًا قصيرًا. ابدأ الدرس للإجابة عليه وتتبّع تقدمك.
جميع دروس البرمجة كائنية التوجه
1الأساليب والسلوك
مقدمة في كتل التنفيذمعامل Selfالأساليب القابلة للتعديلالدوال المرتبطةكتل تنفيذ متعددةتسلسل الأساليبمراجعة - إجراءات المستطيل4مشروع: حيوان أليف افتراضي
تعريف الحيوان الأليفإطعام الحيوان الأليف2التغليف والوحدات البرمجية
أساسيات الوحدات البرمجيةالكلمة المفتاحية Publicالحقول الخاصةدوال Gettersدوال Settersمراجعة - الخزانة الآمنة5الأنواع العامة (Generics)
الـ Structs العامةالـ Methods العامةأنواع عامة متعددةالـ Functions العامةمراجعة - Coordinate Point3التعدادات المتقدمة (Advanced Enums)
التعدادات مع البياناتالأساليب (Methods) في التعداداتمطابقة حالات البياناتمراجعة التعداد Optionملخص - التعداد Shape6تعريف الـ Traits
ما هي الـ Trait؟تنفيذ الـ Traitsالتنفيذات الافتراضيةتجاوز التنفيذات الافتراضيةالـ Traits مع المعاملاتملخص - مشغل الوسائطتدرّب بنفسك: مترجم Rust عبر الإنترنت