In Cairo, gli smart pointer sono strutture dati avanzate che garantiscono una gestione della memoria sicura ed efficiente, aggiungendo funzionalità di sicurezza ai puntatori normali e prevenendo problemi comuni come la dereferenziazione di puntatori nulli o l'accesso a memoria non inizializzata.
Uno smart pointer si comporta come un puntatore normale, ma tiene traccia della proprietà e garantisce un accesso sicuro alla memoria, prevenendo problemi come la dereferenziazione di puntatori nulli o penzolanti.
Cairo fornisce diversi tipi di smart pointer, come Box<T> e Nullable<T>:
Box<T>: memorizza i dati in uno speciale segmento di memoria, ideale per dati di grandi dimensioni o di dimensione dinamica.
Permette di trasferire la proprietà senza copiare i dati.Nullable<T>: punta a un valore valido di tipo T oppure a null, utile per gestire valori opzionali.Gli smart pointer aiutano a prevenire accessi non sicuri alla memoria, garantendo che la memoria venga deallocata automaticamente quando non serve più, riducendo così il rischio di perdite di memoria.
Box<T> per i tipi ricorsiviGli smart pointer come Box<T> permettono di gestire in modo sicuro i tipi ricorsivi, come in un albero binario, allocando la memoria in modo efficiente ed evitando la ricorsione infinita.
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);
}
Gli smart pointer migliorano le prestazioni passando riferimenti ai dati invece di copiare grandi strutture, riducendo il sovraccarico di memoria.
// `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);
}
In Chrono Realms, i Time Keepers hanno spesso a che fare non solo con alberi di linee temporali, ma con le Chrono Chains: sequenze di TimeNode collegati tra loro, ognuno dei quali rappresenta un momento specifico nel tempo. Una Chrono Chain è un percorso lineare di momenti sequenziali, in cui ogni TimeNode si collega al successivo. Queste Chrono Chains sono utili quando si viaggia attraverso una serie di eventi specifici: permettono ai Time Keepers di seguire un'unica linea temporale.
Tuttavia, per gestire Chrono Chains potenzialmente lunghe, i Time Keepers usano gli Smart Pointers (Box<t>)</t> per gestire e attraversare in sicurezza queste liste di momenti, senza causare inutili duplicazioni di memoria o overflow. Ogni TimeNode contiene un riferimento al nodo successivo, formando una struttura ricorsiva.
Il tuo compito, come apprendista, è implementare una Chrono Chain come struttura di lista ricorsiva usando i puntatori intelligenti.
In questo esercizio dovrai:
ChronoChain, che rappresenta una lista di momenti.Box<T> per memorizzare i nodi ricorsivi.ChronoChain a partire da un array di valori u32.ChronoChain e somma i valori memorizzati nella lista.ChronoChain
Crea un enum ricorsivo ChronoChain con due varianti:
End: rappresenta la fine della lista.Link: contiene un valore u32 e un riferimento racchiuso in un box al nodo successivo della catena.Scrivi una funzione ChronoChain::build che prende un array di valori u32 e restituisce una ChronoChain, collegando i valori in sequenza tramite puntatori intelligenti.
Scrivi una funzione ChronoChain::sum che attraversa ricorsivamente la ChronoChain e somma i valori di tutti i nodi.
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);
}
Iscriviti a Exercism per imparare e padroneggiare Cairo con 25 concetti68 esercizi e il mentoring di persone reali, tutto gratis.