Οι έξυπνοι δείκτες στη 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 Chains, δηλαδή ακολουθίες συνδεδεμένων TimeNodes, όπου το καθένα αντιπροσωπεύει μια συγκεκριμένη στιγμή στον χρόνο. Μια Chrono Chain είναι μια ευθεία διαδρομή διαδοχικών στιγμών, όπου κάθε TimeNode συνδέεται με το επόμενο. Αυτές οι Chrono Chains είναι χρήσιμες όταν ταξιδεύεις μέσα από μια σειρά συγκεκριμένων γεγονότων, αφού επιτρέπουν στους Time Keepers να ακολουθήσουν μία μόνο χρονογραμμή.
Ωστόσο, για να χειριστούν αυτές τις δυνητικά μεγάλες Chrono Chains, οι Time Keepers χρησιμοποιούν έξυπνους δείκτες (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 ασκήσεις και πραγματική καθοδήγηση από ανθρώπους, όλα δωρεάν.