L'échec n'est pas une interruption surprise. C'est une valeur de retour.Failure isn't a surprise interruption. It's a return value.
Le Vol 3 a appris à rendre l'illégal impossible à écrire. Mais toutes les erreurs ne sont pas des bugs à proscrire : un fichier qui n'existe pas, un réseau qui tombe, une saisie invalide sont des événements normaux. La plupart des langages les signalent par une exception — un canal parallèle, invisible dans la signature, qui saute par-dessus ton code jusqu'à ce que quelqu'un l'attrape, ou pas. Rust prend le chemin inverse : l'échec est une valeur ordinaire, Result<T, E>, posée dans le type de retour. Le même enum que partout — Ok ou Err — au cœur de la gestion d'erreur la plus honnête qui soit.Vol 3 taught us to make the illegal impossible to write. But not every error is a bug to forbid: a file that isn't there, a network that drops, invalid input are normal events. Most languages signal them with an exception — a parallel channel, invisible in the signature, that leaps over your code until someone catches it, or doesn't. Rust takes the opposite path: failure is an ordinary value, Result<T, E>, placed in the return type. The same enum as everywhere — Ok or Err — at the heart of the most honest error handling there is.
enum Result<T, E> { // exactement la forme d'Option, mais l'absence porte une RAISON Ok(T), // le succès, qui transporte la valeur attendue Err(E), // l'échec, qui transporte ce qui a mal tourné } // lire un fichier peut échouer : le type de retour le DIT fn lire_config(chemin: &str) -> Result<String, std::io::Error> { /* ... */ } let config = lire_config("app.toml"); // config est Result<String, Error> // impossible d'utiliser le String sans d'abord regarder le cas Err en face.
La question qui structure tout le volume : est-ce une erreur attendue, ou un bug ? Un fichier absent, un port occupé, un JSON malformé : ce sont des conditions du monde réel, prévisibles — elles appartiennent au type de retour, en Result. Un invariant qu'on s'était promis et qui se rompt (un index hors borne, un état qui ne devrait jamais arriver) : ça, c'est un bug, et ça relève du panic — le sujet du n°3. Confondre les deux est la première erreur de conception : on ne met pas un bug dans un Result, et on ne fait pas paniquer sur un fichier manquant.The question that structures the whole volume: is this an expected error, or a bug? A missing file, a busy port, malformed JSON: these are predictable real-world conditions — they belong in the return type, as Result. An invariant you promised yourself that breaks (an out-of-bounds index, a state that should never happen): that's a bug, and it's the realm of panic — issue n°3's subject. Confusing the two is the first design mistake: you don't put a bug in a Result, and you don't panic on a missing file.
« Cette fonction peut-elle échouer pour une raison normale ? » Si oui, elle renvoie un Result, et le compilateur force l'appelant à traiter l'échec — exactement comme Option forçait à traiter l'absence. L'erreur cesse d'être une chose qui arrive à ton code pour devenir une chose qui est dans ton code, qu'on lit, transforme et propage.'Can this function fail for a normal reason?' If so, it returns a Result, and the compiler forces the caller to handle the failure — exactly as Option forced handling absence. The error stops being something that happens to your code and becomes something that is in your code, read, transformed and propagated.
Option<T> dit « il y a une valeur, ou rien ». Result<T, E> dit « il y a une valeur, ou un échec — et voici lequel ». Là où None est muet, Err(e) transporte le diagnostic. Tout ce que tu as appris sur Option — match, if let, ?, les combinateurs — se transpose presque tel quel sur Result. C'est le même enum, enrichi d'une raison.Option<T> says 'there's a value, or nothing'. Result<T, E> says 'there's a value, or a failure — and here's which'. Where None is mute, Err(e) carries the diagnosis. Everything you learned about Option — match, if let, ?, the combinators — transfers almost unchanged to Result. It's the same enum, enriched with a reason.