Ownership
En Rust, une donnée sur le tas a un unique propriétaire. C'est lui qui se charge de libérer la mémoire.
Transfert d'ownership
Cette fonction crée un vecteur avec 5 et 12 dedans. C'est v
qui est le propriétaire. En faisant, v2 = v
, on met les données dans v2
qui devient le propriétaire des données. v
ne possède plus rien.
fn main() { let v = vec![5, 12]; let v2 = v; println!("{}", v[0]); // non }
Pareil, si on appelle une fonction sur v
, c'est l'argument dans f
qui est le propriétaire.
#![allow(unused)] fn main() { fn f(argv: Vec<i32>) { ... } }
fn main() { let v = vec![5, 12]; f(v); println!("{}", v[0]); // non }
Une solution pourrait être que la fonction renvoie v
pour que v
redevienne propriétaire des données :
fn main() { let v = vec![5, 12]; v = f(v); println!("{}", v[0]); // non }
Mais ça peut être lourdingue, surtout si une fonction a plusieurs paramètres...
Références et emprunt
#![allow(unused)] fn main() { fn f(argv: &Vec<i32>) { ... } }
Le &
permet d'emprunter des données, les utiliser, mais sans en être propriétaire. La fonction f
ici ne va pas détruire le vecteur. C'est une référence. Penser une référence Rust comme un pointeur C (et pas comme une référence C++), comme une adresse mémoire.
Contrairement à C, le pointeur nul n'existe pas dans le langage Rust. (il existe dans son implémentation)
Déréférencement
Comme en C, *argv
signifie les données à l'adresse argv
.
fn f(argv: &Vec<i32>) { println!("{}", (*argv)[1]); } fn main() { let v = vec![5, 12]; f(&v); println!("{}", v[0]); }
Mais en fait, il y a du déférencement automatique. Donc l'étoile *
peut être omise :
fn f(argv: &Vec<i32>) { println!("{}", argv[1]); } fn main() { let v = vec![5, 12]; f(&v); println!("{}", v[0]); }
Règles d'emprunt
- Une référence ne peut pas vivre plus longtemps que la variable qu'elle référence. Ce code est faux :
#![allow(unused)] fn main() { let reference: &i32; { let x = 5; reference = &x; } println!("{}", reference); }
- Autant de références immutables que l'on veut
- Au plus une référence mutable sur une variable mutable
- Impossible d'avoir une référence mutable et une autre immutable sur une même variable