Parcours
/
Cairo
Cairo
/
Exercices
/
La chaîne temporelle des royaumes de Chrono
La chaîne temporelle des royaumes de Chrono

La chaîne temporelle des royaumes de Chrono

Exercice d'apprentissage

Introduction

En Cairo, les pointeurs intelligents sont des structures de données avancées qui garantissent une gestion sûre et efficace de la mémoire : ils ajoutent des protections aux pointeurs classiques et évitent les problèmes courants, comme le déréférencement d'un pointeur nul ou l'accès à une mémoire non initialisée.

Qu'est-ce qu'un pointeur intelligent ?

Un pointeur intelligent se comporte comme un pointeur classique, mais il garde la trace de la propriété et garantit un accès sûr à la mémoire, ce qui évite les problèmes comme le déréférencement d'un pointeur nul ou suspendu.

Les types de pointeurs intelligents

Cairo fournit plusieurs types de pointeurs intelligents, comme Box<T> et Nullable<T> :

  • Box<T> : stocke les données dans un segment mémoire particulier, ce qui est idéal pour les données volumineuses ou de taille dynamique. Il permet de transférer la propriété sans copier les données.
  • Nullable<T> : pointe vers une valeur valide de type T ou vers null, ce qui est pratique pour gérer des valeurs facultatives.

La sécurité mémoire

Les pointeurs intelligents aident à éviter les accès mémoire dangereux : la mémoire est libérée automatiquement dès qu'elle n'est plus nécessaire, ce qui réduit le risque de fuites de mémoire.

Exemple : utiliser Box<T> pour les types récursifs

Des pointeurs intelligents comme Box<T> permettent de manipuler des types récursifs en toute sécurité, par exemple dans un arbre binaire, en allouant la mémoire efficacement et en évitant la récursion infinie.

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);
}

Les gains de performance

Les pointeurs intelligents améliorent les performances en passant des références aux données plutôt qu'en copiant de grandes structures, ce qui réduit la surcharge mémoire.

// `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);
}

Instructions

Dans Chrono Realms, les Time Keepers n'ont pas affaire qu'à des arbres de lignes temporelles, mais aussi à des Chrono Chains, des séquences de TimeNodes liés, chacun représentant un moment précis dans le temps. Une Chrono Chain est un chemin rectiligne de moments successifs, où chaque TimeNode se connecte au suivant. Ces Chrono Chains sont utiles lorsqu'on voyage à travers une série d'événements précis, car elles permettent aux Time Keepers de suivre une seule ligne temporelle.

Cependant, pour gérer ces Chrono Chains potentiellement longues, les Time Keepers utilisent des pointeurs intelligents (Box<t>)</t> afin de manipuler et de parcourir en toute sécurité ces listes de moments sans causer de duplication ni de débordement de mémoire inutiles. Chaque TimeNode contient une référence vers le nœud suivant, ce qui forme une structure récursive.

Ta tâche, en tant qu'apprenti, consiste à implémenter une Chrono Chain sous la forme d'une structure de liste récursive à l'aide de pointeurs intelligents.

Dans cet exercice, tu vas :

  1. Créer une énumération ChronoChain récursive, qui représente une liste de moments.
  2. Utiliser le pointeur intelligent Box<T> pour stocker les nœuds récursifs.
  3. Implémenter une fonction qui crée une ChronoChain à partir d'un tableau de valeurs u32.
  4. Implémenter une fonction qui parcourt la ChronoChain et additionne les valeurs stockées dans la liste.

1. Définis l'énumération récursive ChronoChain

Crée une énumération récursive ChronoChain avec deux variantes :

  • End : représente la fin de la liste.
  • Link : contient une valeur u32 et une référence vers le nœud suivant dans la chaîne, encapsulée dans un pointeur intelligent.

2. Crée une fonction pour construire une ChronoChain

Écris une fonction ChronoChain::build qui prend un tableau de valeurs u32 et renvoie une ChronoChain, en reliant les valeurs les unes à la suite des autres à l'aide de pointeurs intelligents.

3. Implémente la fonction de somme

Écris une fonction ChronoChain::sum qui parcourt récursivement la ChronoChain et additionne les valeurs de tous les nœuds.

Exemple d'utilisation

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);
}
Modifie via GitHub Le lien s'ouvre dans une nouvelle fenêtre ou un nouvel onglet
Cairo Exercism

Prêt à commencer La chaîne temporelle des royaumes de Chrono ?

Inscris-toi sur Exercism pour apprendre et maîtriser Cairo avec 25 concepts68 exercices, et un vrai mentorat humain, le tout gratuitement.