Розумні вказівники в 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 Хранителі часу часто мають справу не лише з деревами часових ліній, а й із Chrono Chains - послідовностей звʼязаних TimeNodes, кожен із яких представляє конкретний момент часу. Chrono Chain - це прямий шлях із послідовних моментів, де кожен TimeNode зʼєднується з наступним. Ці Chrono Chains стають у пригоді під час подорожі крізь низку конкретних подій, адже вони дають Хранителям часу змогу рухатися однією часовою лінією.
Однак, щоб упоратися з цими потенційно довгими Chrono Chains, Хранителі часу використовують розумні вказівники (Box<t>)</t>, щоб безпечно керувати цими списками моментів і перебирати їх, не спричиняючи зайвого дублювання чи переповнення памʼяті. Кожен TimeNode зберігає посилання на наступний вузол, утворюючи рекурсивну структуру.
Наше завдання як учнів - реалізувати Chrono Chain як рекурсивну структуру списку за допомогою розумних вказівників.
У цій вправі ми зробимо таке:
ChronoChain, що представляє список моментів.Box<T> для зберігання рекурсивних вузлів.ChronoChain з масиву значень u32.ChronoChain й обчислює суму значень, збережених у списку.ChronoChain
Створіть рекурсивний enum ChronoChain із двома варіантами:
End: позначає кінець списку.Link: містить значення u32 і посилання на наступний вузол ланцюга, загорнуте в Box.Напишіть функцію ChronoChain::build, яка приймає масив значень u32 і повертає ChronoChain, зʼєднуючи значення послідовно за допомогою розумних вказівників.
Напишіть функцію 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);
}
Зареєструйтеся на Exercism, щоб вивчати й опановувати Cairo, а також 25 концепцій68 вправ та справжнє наставництво від людей, і все це безкоштовно.