ماکروها بخش قدرتمندی از جعبهابزار یک برنامهنویس Rust هستند و ماکروهای نمونهمحور راهی نسبتاً ساده برای دسترسی به این تواناییاند. بیایید یکی بنویسیم!
ماکرو چیست؟ ویکیپدیا آن را چنین توصیف میکند:
ماکرو (کوتاهشدهی «macroinstruction»، از یونانی μακρός به معنی «بلند») در علوم کامپیوتر قاعده یا الگویی است که مشخص میکند چگونه یک دنبالهی ورودی معین (اغلب دنبالهای از نویسهها) باید بر اساس یک رویهی تعریفشده به یک دنبالهی خروجی جانشین (که آن هم اغلب دنبالهای از نویسهها است) نگاشت شود. فرایند نگاشتی که یک کاربرد ماکرو را به دنبالهای مشخص تبدیل (نمونهسازی) میکند، «بسط ماکرو» نام دارد.
روشنگر بود! اما برای اینکه ملموستر بگوییم، ماکروها نحوهی نگارش ویژهای هستند که به شما اجازه میدهند در زمان کامپایل کد تولید کنید. از ماکروها میتوان برای محاسبه در زمان کامپایل استفاده کرد، اما بیشتر اوقات آنها فقط راه دیگری برای انتزاعی کردن کد شما هستند. برای مثال، احتمالاً قبلاً از println!() و vec![] استفاده کردهاید. هرکدام از اینها تعداد دلخواهی آرگومان میگیرند، بنابراین نمیتوانید آنها را بهصورت توابع ساده بیان کنید. از طرف دیگر، آنها همیشه به مقداری کد کاملاً استاندارد Rust بسط پیدا میکنند. اگر علاقهمند هستید، میتوانید از زیرفرمان cargo expand برای دیدن نتیجهی بسط ماکرو در کدتان استفاده کنید.
برای اطلاعات بیشتر دربارهی ماکروها در Rust، کتاب The Rust Book فصل خوبی دربارهی آنها دارد.
میتوانید با استفاده از ماکروی vec![] یک Vec با طول دلخواه را بهصورت درجا تولید کنید. اما Rust راهی برای تولید درجای HashMap ندارد. این را با نوشتن یک ماکروی hashmap!() اصلاح کنید.
برای مثال، کاربر کتابخانهی شما ممکن است بنویسد hashmap!('a' => 3, 'b' => 11, 'z' => 32). این باید به کد زیر بسط پیدا کند:
{
let mut hm = HashMap::new();
hm.insert('a', 3);
hm.insert('b', 11);
hm.insert('z', 32);
hm
}
توجه داشته باشید که crate maplit ماکرویی ارائه میدهد که این تمرین را بهطور کامل حل میکند. لطفاً بهجای استفاده از این crate، راهحل خودتان را پیادهسازی کنید. پیش از دیدن کد منبع آن هم، خودتان روی مسئله تلاش کنید.