Rust : Display implementation and Rc + RefCell use demo

De Justine's wiki
Aller à la navigation Aller à la recherche

Display and Rc demo

Ce qui va suivre est un petit exemple que je garde comme pense-bête, parce que j'ai du mal avec certains exemples du Rust book...

Il présente :

  • L'implémentation d'un trait
  • L'utilisation de Rc<T> pour avoir plusieurs propriétaires d'un objet
  • L'utilisation de refcell pour pouvoir modifier cet objet.

<source lang="rust"> use std::rc::Rc; use std::cell::RefCell; use std::fmt;

//I create a struct to describe Nessie, the cute little Loch Ness monster plush from Apex Legends.

  1. [derive(Debug)]

struct Nessie {

   color: u32,
   cuteness: u32,

}

//I want to show my Nessie to the world : here's an impl of the Display trait //from the standard fmt lib. impl fmt::Display for Nessie {

   fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
       write!(f, "Nessie has color {}, and is so cute, look : {}", self.color, self.cuteness)
   }

}

//Time to instantiate Nessie (don't worry, it does not hurt) fn main(){

   {
       //I have one Nessie...
       //But since so many people are fond of her, I use a Reference-Counted object so that
       //everyone can have a look at her.
       //The Rc is like a pair of arms holding her. 
       //These arms can't modify Nessie, only hug her.
       let ness = Rc::new( Nessie { color: 100, cuteness: 100 } );
       //Look guys, nessie !
       println!("Look at ness : {}", *ness);
       //Two people want to hug her... But that's cool, since my arms are big, I won't have to 
       //stop hugging her.
       let arms1 = vec![Rc::clone(&ness)];
       let arms2 = vec![Rc::clone(&ness)];
       //How many people are holding her ?
       println!("Nessie is currently hugged by {} people", Rc::strong_count(&ness));
   }


   //Now that's all fine and dandy... But what if someone wants to
   //make her cuter, by changing her cuteness value ? RefCell to the rescue !
   {
       //We start by instantiating Nessie again, but in a different way.
       //We hold Nessie in our Rc arms, but we give her a RefCell, that's like
       //a little jacket we can modify.
       let ness = Rc::new(RefCell::new( Nessie { color: 100, cuteness: 75 } ));
       //Someone Hugs her...
       let arms1 = vec![Rc::clone(&ness)];
       //And shows her around in her little jacket. 
       println!("{:?}", ness);
       //Lets modify our jacketed Nessie to make her cuter.
       //Borrow_mut returns a RefMut<T> we can use to change values. 
       //Mind that she can be modified by one person at a time !
       ness.borrow_mut().cuteness += 100;
       //Did Nessie become cuter in the arms of arms1 ? It did !
       println!("What's in my arms ? {:?}", arms1);
   }

} </source>

Retour:

Look at ness : Nessie has color 100, and is so cute, look : 100
Nessie is currently hugged by 3 people
RefCell { value: Nessie { color: 100, cuteness: 75 } }
What's in my arms ? [RefCell { value: Nessie { color: 100, cuteness: 175 } }]