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

Ωστόσο, για να χειριστούν αυτές τις δυνητικά μεγάλες Chrono Chains, οι Time Keepers χρησιμοποιούν έξυπνους δείκτες (Box<t>)</t> ώστε να διαχειρίζονται και να διατρέχουν με ασφάλεια αυτές τις λίστες στιγμών, χωρίς περιττό διπλασιασμό δεδομένων στη μνήμη ή υπερχείλιση. Κάθε TimeNode κρατάει μια αναφορά στον επόμενο κόμβο, σχηματίζοντας μια αναδρομική δομή.

Η αποστολή σου ως μαθητευόμενος είναι να υλοποιήσεις μια Chrono Chain ως αναδρομική δομή λίστας, χρησιμοποιώντας έξυπνους δείκτες.

Σε αυτή την άσκηση, θα:

  1. Δημιουργήσεις ένα αναδρομικό enum ChronoChain, που αντιπροσωπεύει μια λίστα στιγμών.
  2. Χρησιμοποιήσεις τον έξυπνο δείκτη Box<T> για να αποθηκεύσεις τους αναδρομικούς κόμβους.
  3. Υλοποιήσεις μια συνάρτηση που δημιουργεί μια ChronoChain από έναν πίνακα τιμών u32.
  4. Υλοποιήσεις μια συνάρτηση που διατρέχει τη ChronoChain και αθροίζει τις τιμές που είναι αποθηκευμένες στη λίστα.

1. Όρισε το αναδρομικό enum ChronoChain

Δημιούργησε ένα αναδρομικό enum ChronoChain με δύο παραλλαγές:

  • End: Αντιπροσωπεύει το τέλος της λίστας.
  • Link: Περιέχει μια τιμή u32 και μια αναφορά σε Box στον επόμενο κόμβο της αλυσίδας.

2. Δημιούργησε μια συνάρτηση που φτιάχνει μια ChronoChain

Γράψε μια συνάρτηση ChronoChain::build που παίρνει έναν πίνακα τιμών u32 και επιστρέφει μια ChronoChain, συνδέοντας τις τιμές διαδοχικά με έξυπνους δείκτες.

3. Υλοποίησε τη συνάρτηση αθροίσματος

Γράψε μια συνάρτηση 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 ασκήσεις και πραγματική καθοδήγηση από ανθρώπους, όλα δωρεάν.