تتيح لك وحدات الماكرو كتابة التعليمات البرمجية التي تكتب تعليمات برمجية أخرى. تعرف على العالم الغريب والقوي في ما وراء البرمجة.

يعد إنشاء الكود ميزة ستجدها في معظم لغات البرمجة الحديثة. يمكن أن يساعدك على تقليل تكرار الشفرة المعيارية والتعليمات البرمجية ، وتحديد اللغات الخاصة بالمجال (DSLs) ، وتنفيذ بناء جملة جديد.

يوفر Rust نظامًا ماكروًا قويًا يسمح لك بإنشاء رمز في وقت التجميع لبرمجة أكثر تعقيدًا.

مقدمة إلى وحدات ماكرو الصدأ

وحدات الماكرو هي نوع من البرمجة الوصفية يمكنك الاستفادة منها لكتابة التعليمات البرمجية التي تكتب التعليمات البرمجية. في Rust ، الماكرو هو جزء من التعليمات البرمجية التي تنشئ تعليمات برمجية أخرى في وقت الترجمة.

تعتبر وحدات الماكرو Rust ميزة قوية تتيح لك كتابة التعليمات البرمجية التي تنشئ تعليمات برمجية أخرى في وقت الترجمة لأتمتة المهام المتكررة. تساعد وحدات ماكرو Rust في تقليل تكرار الكود وزيادة قابلية صيانة الكود وقابليته للقراءة.

يمكنك استخدام وحدات الماكرو لإنشاء أي شيء من مقتطفات التعليمات البرمجية البسيطة إلى المكتبات والأطر. تختلف وحدات الماكرو عن وظائف الصدأ لأنها تعمل على التعليمات البرمجية بدلاً من البيانات في وقت التشغيل.

instagram viewer

تحديد وحدات الماكرو في Rust

ستحدد وحدات الماكرو بامتداد ملفات الماكرو! دقيق. ال ملفات الماكرو! يأخذ الماكرو نمطًا وقالبًا كمدخلات. يطابق Rust النمط مقابل رمز الإدخال ويستخدم القالب لإنشاء كود الإخراج.

إليك كيفية تحديد وحدات الماكرو في Rust:

ملفات الماكرو! قل مرحبا {
() => {
println!("مرحبا بالعالم!");
};
}

الجبهة الوطنيةرئيسي() {
قل مرحبا!()؛
}

يحدد الكود أ قل مرحبا الماكرو الذي ينشئ رمزًا لطباعة "Hello، world!". الرمز يطابق () بناء الجملة مقابل إدخال فارغ و println! يقوم الماكرو بإنشاء رمز الإخراج.

إليك نتيجة تشغيل الماكرو في رئيسي وظيفة:

يمكن أن تأخذ وحدات الماكرو وسيطات الإدخال للتعليمة البرمجية التي تم إنشاؤها. إليك ماكرو يأخذ وسيطة واحدة وينشئ رمزًا لطباعة رسالة:

ملفات الماكرو! say_message {
($ message: expr) => {
println!("{}"، رسالة $) ؛
};
}

ال قل_الرسالة يأخذ الماكرو رسالة $ وسيطة ويولد رمز لطباعة الوسيطة باستخدام println! دقيق. ال إكسبر بناء الجملة يطابق الوسيطة ضد أي تعبير Rust.

أنواع وحدات ماكرو الصدأ

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

وحدات الماكرو الإجرائية

تعتبر وحدات الماكرو الإجرائية هي النوع الأقوى والأكثر تنوعًا. تسمح لك وحدات الماكرو الإجرائية بتحديد بناء جملة مخصص يولد كود Rust في نفس الوقت. يمكنك استخدام وحدات الماكرو الإجرائية لإنشاء وحدات ماكرو اشتقاق مخصصة ، ووحدات ماكرو تشبه السمات المخصصة ، ووحدات ماكرو شبيهة بالوظائف المخصصة.

ستستخدم وحدات ماكرو مشتقة مخصصة لتنفيذ البنيات وسمات التعداد تلقائيًا. تستخدم الحزم الشائعة مثل Serde ماكرو اشتقاق مخصص لإنشاء رمز التسلسل وإلغاء التسلسل لهياكل بيانات Rust.

تعد وحدات الماكرو المخصصة التي تشبه السمات سهلة الاستخدام لإضافة التعليقات التوضيحية المخصصة إلى كود Rust. يستخدم إطار عمل الويب Rocket ماكروًا مخصصًا يشبه السمات لتعريف المسارات بإيجاز وسهولة.

يمكنك استخدام وحدات ماكرو مخصصة تشبه الوظيفة لتعريف تعبيرات أو عبارات Rust جديدة. يستخدم صندوق Lazy_static وحدة مخصصة تشبه الوظيفة لتعريف ملف مهيأ كسول المتغيرات الثابتة.

فيما يلي كيفية تحديد ماكرو إجرائي يحدد ماكرو اشتقاق مخصص:

يستخدم proc_macro:: TokenStream ؛
يستخدم اقتباس:: اقتباس ؛
يستخدم syn:: {DeriveInput، parse_macro_input} ؛

ال يستخدم تقوم التوجيهات باستيراد الصناديق والأنواع اللازمة لكتابة ماكرو إجرائي Rust.

# [proc_macro_derive (MyTrait)]
حانةالجبهة الوطنيةmy_derive_macro(الإدخال: TokenStream) -> TokenStream {
يترك ast = parse_macro_input! (المدخلات مثل مشتق المدخلات) ؛
يترك الاسم = & ast.ident؛

يترك الجنرال = اقتباس! {
ضمني MyTrait ل #اسم {
// التنفيذ هنا
}
};

gen.into ()
}

يعرّف البرنامج الماكرو الإجرائي الذي يولد تنفيذ سمة لبنية أو تعداد. يستدعي البرنامج الماكرو بالاسم MyTrait في السمة المشتقة للبنية أو التعداد. يأخذ الماكرو TokenStream كمدخل يحتوي على الكود الذي تم تحليله في شجرة بناء الجملة المجردة (AST) باستخدام الامتداد parse_macro_input! دقيق.

ال اسم المتغير هو الهيكل المشتق أو معرف التعداد ، و يقتبس! يولد الماكرو AST جديد يمثل تنفيذ MyTrait للنوع الذي يتم إرجاعه في النهاية كملف TokenStream مع ال داخل طريقة.

لاستخدام الماكرو ، ستحتاج إلى استيراد الماكرو من الوحدة التي أعلنتها فيها:

// بافتراض أنك أعلنت الماكرو في وحدة my_macro_module

يستخدم my_macro_module:: my_derive_macro ؛

عند التصريح عن البنية أو التعداد الذي يستخدم الماكرو ، ستضيف # [اشتقاق (MyTrait)] السمة إلى الجزء العلوي من الإعلان.

# [اشتقاق (MyTrait)]
هيكلMyStruct {
// الحقول هنا
}

يتوسع إعلان البنية الذي يحمل السمة إلى تنفيذ MyTrait سمة الهيكل:

ضمني MyTrait ل هيكلي {
// التنفيذ هنا
}

يتيح لك التنفيذ استخدام طرق في ملف MyTrait السمة على MyStruct حالات.

سمات وحدات الماكرو

وحدات ماكرو السمات هي وحدات ماكرو يمكنك تطبيقها على عناصر Rust مثل الهياكل والتعدادات والوظائف والوحدات النمطية. تتخذ وحدات ماكرو السمات شكل سمة متبوعة بقائمة من الوسائط. يوزع الماكرو الوسيطة لإنشاء رمز Rust.

ستستخدم وحدات ماكرو السمات لإضافة سلوكيات مخصصة وتعليقات توضيحية إلى شفرتك.

فيما يلي ماكرو سمة يضيف سمة مخصصة إلى بنية Rust:

// استيراد الوحدات النمطية لتعريف الماكرو
يستخدم proc_macro:: TokenStream ؛
يستخدم اقتباس:: اقتباس ؛
يستخدم syn:: {parse_macro_input، DeriveInput، AttributeArgs}؛

# [proc_macro_attribute]
حانةالجبهة الوطنيةmy_attribute_macro(attr: TokenStream ، item: TokenStream) -> TokenStream {
يترك args = parse_macro_input! مثل AttributeArgs) ؛
يترك المدخلات = parse_macro_input! (item مثل مشتق المدخلات) ؛
يترك الاسم = & input.ident ؛

يترك الجنرال = اقتباس! {
#مدخل
ضمني #اسم {
// سلوك مخصص هنا
}
};

gen.into ()
}

يأخذ الماكرو قائمة من الوسائط و تعريف هيكل وينشئ بنية معدلة بالسلوك المخصص المحدد.

يأخذ الماكرو وسيطتين كمدخلات: السمة المطبقة على الماكرو (محللًا بامتداد parse_macro_input! الماكرو) والعنصر (محلل بامتداد parse_macro_input! دقيق). يستخدم الماكرو ملف يقتبس! ماكرو لإنشاء الكود ، بما في ذلك عنصر الإدخال الأصلي وعنصر إضافي ضمني الذي يحدد السلوك المخصص.

أخيرًا ، تقوم الوظيفة بإرجاع الكود الذي تم إنشاؤه كملف TokenStream مع ال داخل() طريقة.

قواعد الماكرو

قواعد الماكرو هي أكثر أنواع وحدات الماكرو وضوحًا ومرونة. تسمح لك قواعد الماكرو بتعريف بناء جملة مخصص يتوسع إلى كود Rust في وقت الترجمة. تحدد قواعد الماكرو وحدات ماكرو مخصصة تطابق أي تعبير أو عبارة صدأ.

ستستخدم قواعد الماكرو لإنشاء رمز معياري لاستخلاص التفاصيل ذات المستوى المنخفض.

إليك كيفية تحديد قواعد الماكرو واستخدامها في برامج Rust:

ملفات الماكرو! make_vector {
($ ($ x: expr)، *) => {
{
يتركموت ت = Vec::جديد()؛
$(
v.push ($ x) ؛
)*
الخامس
}
};
}

الجبهة الوطنيةرئيسي() {
يترك ت = make_vector! [1, 2, 3];
println!("{:?}"، الخامس)؛ // طباعة "[1، 2، 3]"
}

يحدد البرنامج أ Make_vector! ماكرو يقوم بإنشاء متجه جديد من قائمة التعبيرات المفصولة بفواصل في ملف رئيسي وظيفة.

داخل الماكرو ، يطابق تعريف النمط الوسيطات التي تم تمريرها إلى الماكرو. ال $ ($ x: expr) ، * يتطابق بناء الجملة مع أي تعبيرات مفصولة بفواصل تم تحديدها على أنها x دولار.

ال $( ) يتكرر بناء الجملة في كود التوسيع عبر كل تعبير في قائمة الوسائط التي تم تمريرها إلى الماكرو بعد ذلك قوس الإغلاق ، مشيرًا إلى أن التكرارات يجب أن تستمر حتى تعالج الماكرو جميع ملفات التعبيرات.

تنظيم مشاريع الصدأ الخاصة بك بكفاءة

تعمل وحدات ماكرو Rust على تحسين تنظيم التعليمات البرمجية من خلال السماح لك بتعريف أنماط التعليمات البرمجية القابلة لإعادة الاستخدام والتجريدات. يمكن أن تساعدك وحدات الماكرو في كتابة تعليمات برمجية أكثر إيجازًا وتعبيرية دون تكرار عبر أجزاء المشروع المختلفة.

أيضًا ، يمكنك تنظيم برامج Rust في صناديق ووحدات نمطية لتحسين تنظيم الكود ، وإعادة الاستخدام ، والتفاعل مع الصناديق والوحدات النمطية الأخرى.