مسیرها
/
Cairo
Cairo
/
تمرین‌ها
/
قلمروهای زمان: زنجیره‌ی زمان
قلمروهای زمان: زنجیره‌ی زمان

قلمروهای زمان: زنجیره‌ی زمان

تمرین یادگیری

مقدمه

«اشاره‌گرهای هوشمند» در Cairo ساختارهای داده‌ی پیشرفته‌ای هستند که با افزودن ویژگی‌های ایمنی به اشاره‌گرهای معمولی، مدیریت حافظه‌ی ایمن و کارآمد را تضمین می‌کنند و از بروز مشکلات رایجی مثل ارجاع‌زدایی از اشاره‌گر تهی یا دسترسی به حافظه‌ی مقداردهی‌نشده جلوگیری می‌کنند.

اشاره‌گر هوشمند چیست؟

اشاره‌گر هوشمند مثل یک اشاره‌گر معمولی رفتار می‌کند، اما مالکیت را ردیابی می‌کند و دسترسی ایمن به حافظه را تضمین می‌کند و جلوی مشکلاتی مثل ارجاع‌زدایی از اشاره‌گر تهی یا اشاره‌گر معلق را می‌گیرد.

انواع اشاره‌گرهای هوشمند

Cairo چند نوع اشاره‌گر هوشمند در اختیار شما می‌گذارد، مثل Box<T> و Nullable<T>:

  • Box<T>: داده را در یک بخش حافظه‌ی ویژه ذخیره می‌کند و برای داده‌های بزرگ یا با اندازه‌ی پویا ایدئال است. امکان انتقال مالکیت را بدون کپی کردن داده فراهم می‌کند.
  • Nullable<T>: به یک مقدار معتبر از نوع T یا به null اشاره می‌کند و برای کار با مقادیر اختیاری به کار می‌آید.

ایمنی حافظه

اشاره‌گرهای هوشمند به جلوگیری از دسترسی ناایمن به حافظه کمک می‌کنند و تضمین می‌کنند که حافظه وقتی دیگر لازم نیست، به‌طور خودکار آزاد شود؛ این‌گونه خطر نشت حافظه کاهش می‌یابد.

مثال: استفاده از Box<T> برای انواع بازگشتی

اشاره‌گرهای هوشمندی مثل Box<T> با تخصیص کارآمد حافظه و پرهیز از بازگشت بی‌پایان، امکان کار ایمن با انواع بازگشتی را فراهم می‌کنند؛ مثلاً در یک درخت دودویی.

use core::box::{BoxTrait};

#[derive(Copy, Drop)]
enum BinaryTree {
    Leaf: u32,
    Node: (u32, Box<BinaryTree>, Box<BinaryTree>),
}

fn main() {
    let leaf1 = BinaryTree::Leaf(1);
    let leaf2 = BinaryTree::Leaf(2);
    let node = BinaryTree::Node((3, BoxTrait::new(leaf1), BoxTrait::new(leaf2)));
    println!("{:?}", node);
}

مزایای کارایی

اشاره‌گرهای هوشمند با ارسال ارجاع به داده به‌جای کپی کردن ساختارهای بزرگ، کارایی را بهبود می‌دهند و سرباز حافظه را کم می‌کنند.

// `Cart` is a large struct that contains a lot of information
fn pass_pointer(cart: Box<Cart>) {
    let cart = cart.unbox();
    println!("{} is shopping today and bought {} items", cart.buyer, cart.items);
}

دستورالعمل‌ها

در Chrono Realms، Time Keepers اغلب نه فقط با درخت‌های خطوط زمانی، بلکه با Chrono Chainها هم سر و کار دارند، یعنی دنباله‌هایی از TimeNodeهای به‌هم‌پیوسته که هر کدام نماینده‌ی لحظه‌ای مشخص در زمان‌اند. یک Chrono Chain مسیری مستقیم از لحظه‌های پشت‌سرهم است که در آن هر TimeNode به گره بعدی وصل می‌شود. این Chrono Chainها وقتی در حال سفر از میان مجموعه‌ای از رویدادهای مشخص هستید مفیدند، چون به Time Keepers اجازه می‌دهند یک خط زمانی واحد را دنبال کنند.

اما برای کار با این Chrono Chainهای بالقوه بلند، Time Keepers از اشاره‌گرهای هوشمند (Box<T>) استفاده می‌کنند تا این فهرست‌های لحظه‌ها را به شکلی ایمن مدیریت و پیمایش کنند، بدون آنکه حافظه بی‌دلیل تکرار شود یا دچار سرریز شود. هر TimeNode ارجاعی به گره بعدی در خود نگه می‌دارد و به این ترتیب ساختاری بازگشتی می‌سازد.

وظیفه‌ی شما به عنوان کارآموز این است که یک Chrono Chain را به صورت ساختاری فهرست‌مانند و بازگشتی، با استفاده از اشاره‌گرهای هوشمند پیاده‌سازی کنید.

در این تمرین، این کارها را انجام می‌دهید:

  1. یک enum بازگشتی به نام ChronoChain بسازید که نماینده‌ی فهرستی از لحظه‌ها باشد.
  2. از اشاره‌گر هوشمند Box<T> برای نگهداری گره‌های بازگشتی استفاده کنید.
  3. تابعی پیاده‌سازی کنید که یک ChronoChain را از آرایه‌ای از مقادیر u32 بسازد.
  4. تابعی پیاده‌سازی کنید که ChronoChain را پیمایش کند و مقادیر ذخیره‌شده در فهرست را جمع بزند.

1. تعریف enum بازگشتی ChronoChain

یک enum بازگشتی به نام ChronoChain با دو گونه بسازید:

  • End: پایان فهرست را نشان می‌دهد.
  • Link: یک مقدار u32 و یک ارجاع جعبه‌ای به گره بعدی زنجیره را در خود نگه می‌دارد.

2. نوشتن تابعی برای ساخت ChronoChain

تابعی به نام ChronoChain::build بنویسید که آرایه‌ای از مقادیر u32 را می‌گیرد و یک ChronoChain برمی‌گرداند و مقادیر را به ترتیب، با اشاره‌گرهای هوشمند، به هم پیوند می‌دهد.

3. پیاده‌سازی تابع sum

تابعی به نام ChronoChain::sum بنویسید که ChronoChain را به صورت بازگشتی پیمایش کند و مقادیر همه‌ی گره‌ها را جمع بزند.

نمونه‌ی استفاده

fn main() {
    // Create a ChronoChain from an array of values
    let chrono_chain = ChronoChain::build(array![10, 20, 30]);

    // Sum the values in the ChronoChain
    let total_sum = chrono_chain.sum();

    println!("Total Time Power: {}", total_sum);
}
ویرایش از طریق GitHub این لینک در پنجره یا زبانه‌ی جدیدی باز می‌شود
Cairo Exercism

آماده‌اید قلمروهای زمان: زنجیره‌ی زمان را شروع کنید؟

در Exercism ثبت‌نام کنید تا Cairo را همراه با 25 مفهوم68 تمرین و مربی‌گری انسانی واقعی یاد بگیرید و در آن استاد شوید، همه‌ی این‌ها رایگان.