Passer au contenu principal
eLearner.app
Module 3 · Leçon 2 sur 26/14 dans le cours~15 min
Leçons du module (2/2)

Références et Borrowing

En Rust, passer continuellement la propriété (ownership) d'une variable à une fonction et la lui faire renvoyer peut être très fastidieux. Pour résoudre ce problème, Rust utilise les références (references).

Créer une référence à une valeur s'appelle le Borrowing (emprunt).

Références Immuables

Une référence se déclare en faisant précéder le type ou la variable du symbole &. Par défaut, les références sont immuables : elles permettent de lire la valeur mais pas de la modifier.

Code
fn main() {
    let s1 = String::from("hello");

    // Passiamo un riferimento a s1, non l'ownership
    let len = calculate_length(&s1);

    // s1 è ancora utilizzabile qui!
    println!("La lunghezza di '{}' è {}.", s1, len);
}

fn calculate_length(s: &String) -> usize { // s è un riferimento a una String
    s.len()
} // Qui s esce dallo scope, ma poichè non possiede il valore, non succede nulla

Références Mutables

Si vous avez besoin de modifier une valeur empruntée, vous devez utiliser une référence mutable via &mut. La variable d'origine doit également être déclarée mutable avec mut :

Code
fn main() {
    let mut s = String::from("hello");

    // Passiamo un riferimento mutabile
    change(&mut s);

    println!("{}", s); // Stampa "hello, world"
}

fn change(some_string: &mut String) {
    some_string.push_str(", world");
}

Les Règles d'Or du Borrowing

Pour prévenir les corruptions de mémoire et les accès concurrents aux données (data races) au moment de la compilation, Rust impose deux règles fondamentales :

  1. Vous pouvez avoir un nombre quelconque de références immuables (&T) à une valeur en même temps.
  2. OU ALORS vous pouvez avoir exactement une seule référence mutable (&mut T) à une valeur à la fois.

Vous ne pouvez absolument pas mélanger références immuables et mutables pour la même valeur dans la même portée :

Code
let mut s = String::from("hello");

let r1 = &s; // Valido
let r2 = &s; // Valido
// let r3 = &mut s; // ERRORE DI COMPILAZIONE! Non puoi creare &mut s se s è già presa in prestito come immutabile

La Portée des Références et Non-Lexical Lifetimes (NLL)

Auparavant, la portée d'une référence durait obligatoirement jusqu'à la fin du bloc dans lequel elle était créée. Aujourd'hui, le compilateur de Rust est plus intelligent grâce aux Non-Lexical Lifetimes (NLL) : la portée d'une référence se termine à la dernière ligne où elle est utilisée, pas nécessairement à la fin du bloc.

Cela rend le code suivant valide :

Code
let mut s = String::from("hello");
let r1 = &s;
let r2 = &s;
println!("{} e {}", r1, r2); // Ultimo uso di r1 e r2. I riferimenti immutabili scadono qui!

let r3 = &mut s; // Valido! Nessun riferimento immutabile è attivo a questo punto

À toi de jouer

Exercice#rust.m3.l2.e1
Tentatives : 0Chargement…

Passez une référence immuable de s1 à la fonction calculate_length à l'aide du symbole &.

Chargement de l'éditeur…
Afficher l'indice

Remplacez `/* TODO \_/`par`&s1` pour passer une référence immuable à la chaîne.

Solution disponible après 3 tentatives

Exercice#rust.m3.l2.e2
Tentatives : 0Chargement…

Rendez la variable s mutable (let mut s) et passez une référence mutable (&mut s) à la fonction change pour lui permettre de modifier la chaîne.

Chargement de l'éditeur…
Afficher l'indice

Utilisez `let mut s`au lieu de`let s`et appelez`change(&mut s);`.

Solution disponible après 3 tentatives

Exercice#rust.m3.l2.e3
Tentatives : 0Chargement…

Déclarez une variable s contenant String::from("Rust"). Créez deux références immuables distinctes r1 et r2 à s, et enfin affichez les deux références séparées par un espace en utilisant la macro println!.

Chargement de l'éditeur…
Afficher l'indice

Assignez `let r1 = &s;` et `let r2 = &s;` pour obtenir deux références immuables, puis affichez-les avec `println!("{} {}", r1, r2);`.

Solution disponible après 3 tentatives