Présentation du langage Rust
Édition Rust 2024 — langage système | sécurité de la mémoire sans GC | concurrence intrépide | abstractions à coût nul
Paradigme
Multi-paradigme : impératif, fonctionnel, orienté objet (traits), orienté données. Typage statique avec inférence complète, système de types nominaux, types de données algébriques. Compilation via LLVM. Le vérificateur d'emprunt applique la sécurité de la mémoire au moment de la compilation.
Espèces
| Catégorie |
Espèces |
| Signé en entier |
i8 i16 i32 i64 i128 isize |
| Entier non signé |
u8 u16 u32 u64 u128 usize |
| Flotteur |
f32 f64 |
| Booléen |
bool |
| Char |
char (scalaire Unicode 4 octets) |
| Unité |
() |
| Tranche |
&[T] &mut [T] |
| Tableau |
[T; N] |
| Tuple |
(T1, T2, ...) |
| Référence |
&T &mut T |
| Pointeur brut |
*const T *mut T |
| Options |
Option<T> |
| Résultat |
Result<T, E> |
| Chaîne |
String &str |
| Boîte |
Box<T> (allocation de tas) |
| Vec |
Vec<T> (tableau dynamique) |
| Pointeurs intelligents |
Rc<T> Arc<T> Cell<T> RefCell<T> |
| Pointeur de fonction |
fn(T) -> U |
| Fermeture |
|args| body (type unique par fermeture) |
| Objet de trait |
dyn Trait |
| Jamais |
! (divergent) |
Déclarations
| Construire |
Syntaxe |
Remarques |
| Fonction |
fn name(params) -> Ret { body } |
|
| Méthode |
fn name(&self, params) -> Ret { body } |
Dans impl bloquer |
| Variable |
let x = expr; |
Immuable par défaut |
| Mutable |
let mut x = expr; |
|
| Déstructuration |
let (a, b) = tuple; |
|
| Constante |
const NAME: T = expr; |
Au moment de la compilation, en ligne |
| Statique |
static NAME: T = expr; |
Adresse fixe |
| Structure |
struct Name { field: T } |
Champs nommés |
| Structure de tuple |
struct Name(T1, T2); |
|
| Structure d'unité |
struct Name; |
|
| Énumération |
enum Name { Variant, Var(T) } |
ADT |
| Syndicat |
union Name { f1: T1, f2: T2 } |
Dangereux |
| Caractère |
trait Name { fn method(&self); } |
|
| Implémenter |
impl Type { fn ... } |
|
| Trait implémenté |
impl Trait for Type { fn ... } |
|
| Tapez un alias |
type Alias = T; |
|
| Importer |
use crate::module::Item; |
|
| Macro |
macro_rules! name { ... } |
|
| Module |
mod name; |
|
| Caisse |
extern crate name; (édition 2015) |
|
Propriété et emprunt
Each value has exactly one owner.
Ownership can be moved (assignment, function call).
References (&T) borrow without taking ownership.
Mutable references (&mut T) are exclusive — only one at a time.
References must never outlive their referent (lifetimes).
Règles d'emprunt
- Un
&mut T XOR plusieurs &T à tout moment
- Les références sont toujours valides (pas de pointeurs pendants)
- Durées de vie élidées lorsqu'elles sont sans ambiguïté (
'a, 'static)
Flux de contrôle
| Construire |
Syntaxe |
Remarques |
| Si |
if cond { ... } else { ... } |
Expression |
| Si-laisser |
if let Pattern(expr) = val { ... } |
Déstructuration + correspondance |
| Tandis que |
while cond { ... } |
|
| Pendant que je laisse |
while let Some(v) = opt { ... } |
|
| Pour |
for x in iter { ... } |
Utilise IntoIterator |
| Boucle |
loop { ... } |
Infini (peut break avec valeur) |
| Correspondance |
match expr { Pattern => body, ... } |
exhaustif |
| Pause |
break; / break val; |
|
| Continuer |
continue; |
|
| Retour |
return expr; |
L'expression à la fin du bloc renvoie également |
Modèles de correspondance
Pattern := Literal | Identifier | _ | ref | mut | @ binding
| Tuple(x, y) | Struct { field } | Enum::Variant(x)
| x | y (OR) | x @ y (bind) | .. (rest)
| ... (inclusive range) | ..= (inclusive range)
Guards := Pattern if condition => body
Opérateurs
| Catégorie |
Opérateurs |
| Arithmétique |
+ - * / % |
| Comparaison |
== != < > <= >= |
| Logique |
&& || ! |
| Au niveau du bit |
& | ^ ! << >> |
| Composé |
+= -= *= /= %= &= |= ^= <<= >>= |
| Gamme |
.. ..= .. (semi-ouvert) ..= (inclus) |
| Déf. |
*expr |
| Référence |
&expr &mut expr |
| Point d'interrogation |
expr? (retour anticipé sur Err/None) |
| Turbopoisson |
::<T> (type annotation sur les génériques) |
| Attribut |
#[attr] #![attr] |
Système de traits
Traits standards (sélectionnés)
| Caractère |
Objectif |
Clone |
Copie complète (x.clone()) |
Copy |
Copie au niveau du bit (implicite, opt-in) |
Drop |
Destructeur |
Default |
Valeur par défaut |
Debug |
Formater avec {:?} |
Display |
Format destiné à l'utilisateur {} |
Eq / PartialEq |
Comparaison d'égalité |
Ord / PartialOrd |
Comparaison des commandes |
Hash |
Hachage |
Iterator |
fn next(&mut self) -> Option<Item> |
IntoIterator |
Convertir en itérateur |
From / Into |
Conversion de types |
TryFrom / TryInto |
Conversion faillible |
Deref |
Déréférencement implicite |
AsRef / AsMut |
Conversion de référence |
Borrow / BorrowMut |
Emprunter comme un autre type |
Send / Sync |
Marqueurs de sécurité du fil |
Sized |
Taille connue au moment de la compilation |
Fn FnMut FnOnce |
Caractéristiques de fermeture |
impl Trait / dyn Trait
impl Trait — type de retour opaque (envoi statique)
dyn Trait — objet de trait (répartition dynamique)
where clauses pour les limites complexes : fn f<T>() where T: Clone + Debug
Génériques
fn id<T: Display>(x: T) -> T { x }
struct Pair<T, U> { first: T, second: U }
enum Option<T> { Some(T), None }
impl<T: Clone> Pair<T, T> { fn duplicate(&self) -> Self { ... } }
Modèle de mémoire
Allocation
- Pile : variables locales, tableaux de taille fixe
- Tas :
Box<T>, Vec<T>, String, Rc<T>, Arc<T>
alloc / Layout pour affectation manuelle (dans std::alloc)
Pointeurs intelligents
Box<T> — allocation de tas détenue, propriétaire unique
Rc<T> — comptage de références (non threadsafe)
Arc<T> — comptage de références atomique (threadsafe)
Cell<T> — mutabilité intérieure pour Copy genres
RefCell<T> — vérification de l'emprunt à l'exécution
Mutex<T> / RwLock<T> — mutabilité intérieure sécurisée pour les threads
UnsafeCell<T> — mutabilité intérieure brute
Concurrence
| Primitif |
Emplacement |
std::thread::spawn |
Création de fil de discussion |
std::sync::mpsc |
Chaînes multiproducteurs et mono-consommateur |
crossbeam::channel |
Canaux multi-producteurs, multi-consommateurs (externes) |
Mutex<T> RwLock<T> |
Primitives de synchronisation |
Arc<T> |
Comptage de référence atomique |
std::sync::Barrier Condvar |
Coordination |
async/await (depuis 1.39) |
Async/await avec contrats à terme |
tokio / async-std |
Runtimes asynchrones (externes) |
std::sync::Once OnceLock LazyLock |
Initialisation unique |
Bibliothèque standard (modules sélectionnés)
| Module |
Contenu |
std::io |
Read Write BufRead BufReader BufWriter Stdin Stdout |
std::fs |
File read write create_dir remove_file metadata |
std::net |
TcpStream TcpListener UdpSocket IpAddr |
std::collections |
Vec HashMap HashSet BTreeMap BTreeSet LinkedList VecDeque BinaryHeap |
std::path |
Path PathBuf |
std::env |
args var current_dir temp_dir |
std::process |
Command Output Child exit |
std::time |
Duration Instant SystemTime |
std::sync |
Mutex RwLock Arc Barrier Condvar Once mpsc |
std::thread |
spawn sleep park yield_now current |
std::ffi |
CString CStr OsString OsStr |
std::os |
Extensions spécifiques à la plateforme |
std::ptr |
read write null NonNull addr_of addr_of_mut |
Gestion des erreurs
// Recoverable: Result<T, E>
fn div(a: i32, b: i32) -> Result<i32, String> {
if b == 0 { Err("division by zero".into()) }
else { Ok(a / b) }
}
let r = div(10, 2)?; // early return on Err
// Unrecoverable: panic!
panic!("something went wrong");
// Expected/unexpected split
// Result for recoverable, panic for programmer errors
Rust non sécurisé
unsafe { ... } les blocs permettent :
- Déréférencement de pointeur brut
- Appeler des fonctions non sécurisées (FFI)
- Access/modify statique mutable
- Implémenter des traits dangereux
- Accès au terrain syndical
Le vérificateur d'emprunt s'applique toujours à l'intérieur de unsafe.
Tests
#[test]
fn test_addition() {
assert_eq!(2 + 2, 4);
assert!(true);
assert_ne!(1, 2);
}
Attributs des tests
#[test] #[should_panic] #[ignore] #[cfg(test)] #[bench]
| Composant |
Objectif |
rustc |
Compilateur (LLVM back-end) |
cargo |
Gestionnaire de packages, système de build |
rustup |
Gestionnaire de chaîne d'outils |
rustfmt |
Formateur de code |
clippy |
Linter |
rust-analyzer |
serveur LSP |
cargo-doc |
Générateur de documentation |
cargo-test |
Testeur |
cargo-bench |
Repères |
cargo-clippy |
Contrôles de charpie |
Éditions
| Édition |
Changements clés |
| 2015 |
Édition stable initiale |
| 2018 |
Durées de vie non lexicales, modifications du système de modules, impl Trait, dyn Trait |
| 2021 |
Modifications du prélude, IntoIterator pour les baies, champ d'édition Cargo.toml requis |
| 2024 |
impl Trait partout, gen des blocs, unsafe attributs, if let chaînes stables, ne tapez jamais ! stable |
Compilation
rustc file.rs # compile
cargo new project # new project
cargo build # debug build
cargo build --release # release build
cargo run # build + run
cargo test # run tests
cargo doc --open # generate docs
cargo check # type-check without codegen
Cibles
x86_64-unknown-linux-gnu aarch64-unknown-linux-gnu x86_64-pc-windows-msvc x86_64-apple-darwin wasm32-unknown-unknown wasm32-wasi thumbv7em-none-eabihf (plus de 100 cibles)
Interopérabilité C
// FFI declaration
extern "C" {
fn printf(fmt: *const u8, ...) -> i32;
}
// Linking
#[link(name = "m")]
extern "C" { fn sqrt(x: f64) -> f64; }
// ABI types
// i32 → c_int, u64 → c_ulonglong, *const T → *const c_void