From e43fbd00ec37c409b760aa91637261b938505c37 Mon Sep 17 00:00:00 2001 From: Thomas Ramirez Date: Thu, 21 Dec 2017 06:59:52 +0100 Subject: [PATCH 01/20] Translation Setup: README.md & TRANSLATION.md In order to help new translators understand the workflow. --- README.md | 39 +++++++++++------------------------ second-edition/TRANSLATING.md | 16 ++++++++++++++ 2 files changed, 28 insertions(+), 27 deletions(-) create mode 100644 second-edition/TRANSLATING.md diff --git a/README.md b/README.md index d7d5f28264..5c1d2dec83 100644 --- a/README.md +++ b/README.md @@ -1,49 +1,34 @@ -# NOTICE ABOUT STATUS - -The second edition of The Rust Programming Language is getting ever closer to being printed! -This means we're not able to make large changes to chapters that are in any column to the -right of, and including, the "Frozen" column [on our Project board][proj]. Issues or pull -requests submitted for frozen chapters are welcome but will be closed until we start work -on a third edition. Thank you! - -[proj]: https://github.com/rust-lang/book/projects/1 +> **This is a fork of [rust-lang/book](https://github.com/rust-lang/book) in order to translate the English (second-edition) book in French.** +> +> Please read the help [TRANSLATE.md](https://github.com/quadrifoglio/rust-book-fr/blob/master/second-edition/TRANSLATING.md) ! # The Rust Programming Language [![Build Status](https://travis-ci.org/rust-lang/book.svg?branch=master)](https://travis-ci.org/rust-lang/book) -This repo contains two editions of “The Rust Programming Language”; we -recommend starting with the second edition. +This repo contains two editions of “The Rust Programming Language”. -The second edition is a rewrite that will be printed by No Starch Press, -available around May 2018. Check [the No Starch Page][nostarch] for the latest -information on the release date and how to order. +The second edition is a rewrite that will be printed by NoStarch Press, +available around October 2017. -[nostarch]: https://nostarch.com/rust +[You can read it online][html]; the last few chapters aren't completed yet, but +the first half of the book is much improved from the first edition. We recommend +starting with the second edition. -You can read the book for free online! Please see the book as shipped with the -latest [stable], [beta], or [nightly] Rust releases. Be aware that issues in -those versions may have been fixed in this repository already. - -[stable]: https://doc.rust-lang.org/stable/book/second-edition/ -[beta]: https://doc.rust-lang.org/beta/book/second-edition/ -[nightly]: https://doc.rust-lang.org/nightly/book/second-edition/ +[html]: http://rust-lang.github.io/book/ [The first edition is still available to read online][first]. [first]: https://doc.rust-lang.org/book/ - ## Requirements -Building the book requires [mdBook], ideally the same version that -[rust-lang/rust uses in this file][rust-mdbook]. To get it: +Building the book requires [mdBook] >= v0.0.13. To get it: [mdBook]: https://github.com/azerupi/mdBook -[rust-mdbook]: https://github.com/rust-lang/rust/blob/master/src/tools/rustbook/Cargo.toml ```bash -$ cargo install mdbook --vers [version-num] +$ cargo install mdbook ``` ## Building diff --git a/second-edition/TRANSLATING.md b/second-edition/TRANSLATING.md new file mode 100644 index 0000000000..f0ae0b2ce1 --- /dev/null +++ b/second-edition/TRANSLATING.md @@ -0,0 +1,16 @@ +# Translation process + +1. Ask for the access rights to the french fork on the [initial issue](https://github.com/rust-lang/book/issues/808). +2. Choose a chapter to work on, from the ["french translations" board](https://github.com/quadrifoglio/rust-book-fr/projects/1). Make sure that the original writers marked it as "frozen", and +that the source is is up to date with the [original version](https://github.com/rust-lang/book). +3. Please create a [branch](https://github.com/quadrifoglio/rust-book-fr/branches) in order to work on your translation. +4. Translate the chapter. +5. When you are satisfied with your translation, and want feedback/help on your work, please open a [PR](https://github.com/quadrifoglio/rust-book-fr/pulls). + +When the PR is created, you can ask for a review from the other contributors. +You can also help by taking a look at the opened PRs, do not hesitate to comment or provide corrections. + +## Tool suggestions + +- [BonPatron](http://bonpatron.com/) +- [DeepL Translator](https://www.deepl.com/translator) From abb992df492ae8afa45eba6b1c0e1ecb46e341d1 Mon Sep 17 00:00:00 2001 From: Jimskapt Date: Tue, 12 Dec 2017 20:54:16 +0100 Subject: [PATCH 02/20] Translation of whole ch09-00 in French. --- second-edition/src/ch09-00-error-handling.md | 46 +++++++++++--------- 1 file changed, 25 insertions(+), 21 deletions(-) diff --git a/second-edition/src/ch09-00-error-handling.md b/second-edition/src/ch09-00-error-handling.md index 4efd72956e..9254702d85 100644 --- a/second-edition/src/ch09-00-error-handling.md +++ b/second-edition/src/ch09-00-error-handling.md @@ -1,24 +1,28 @@ -# Error Handling +# Gestion des Erreurs -Rust’s commitment to reliability extends to error handling. Errors are a fact -of life in software, so Rust has a number of features for handling situations -in which something goes wrong. In many cases, Rust requires you to acknowledge -the possibility of an error occurring and take some action before your code -will compile. This requirement makes your program more robust by ensuring that -you’ll discover errors and handle them appropriately before you’ve deployed -your code to production! +L'engagement de Rust envers la fiabilité concerne aussi la gestion des erreurs. +Les erreurs font partie de la vie des programmes informatiques, c'est pourquoi +Rust a des dispositifs pour gérer les situations où les choses se passent mal. +Dans de nombreux cas, Rust exige que vous anticipiez les erreurs possibles et +que vous preniez des dispositions avant de compiler votre code. Cette exigence +rends votre programme plus résiliant en s'assurant que vous détectiez et gérez +les erreurs correctement avant même que vous déployez votre code en production +! -Rust groups errors into two major categories: *recoverable* and *unrecoverable* -errors. Recoverable errors are situations in which it’s reasonable to report -the problem to the user and retry the operation, like a file not found error. -Unrecoverable errors are always symptoms of bugs, like trying to access a -location beyond the end of an array. +Rust classe les erreurs dans deux catégories principales : les erreurs +*récupérables* et *non récupérables*. Les erreurs récupérables se produisent +dans des situations dans lesquelles il est utile de signaler l'erreur à +l'utilisateur et de relancer l'opération, comme par exemple une erreur lorsque +un fichier n'a pas été trouvé. +Les erreurs non récupérables sont toujours liées à des bogues, comme essayer +d'accéder à un caractère au-delà de la fin d'un tableau. -Most languages don’t distinguish between these two kinds of errors and handle -both in the same way using mechanisms like exceptions. Rust doesn’t have -exceptions. Instead, it has the type `Result` for recoverable errors and -the `panic!` macro that stops execution when it encounters unrecoverable -errors. This chapter covers calling `panic!` first and then talks about -returning `Result` values. Additionally, we’ll explore considerations to -take into account when deciding whether to try to recover from an error or to -stop execution. +La plupart des langages de programmation ne font pas de distinction entre ces +deux types d'erreurs et les gèrent de la même manière, comme les exceptions. +Rust n'a pas d'exceptions. À la place, il a les valeurs `Result` pour les +erreurs récupérables, et la macro `panic!` qui arrête l'exécution quand il +se heurte à des erreurs irrécupérables. Nous allons commencer ce chapitre par +expliquer l'utilisation de `panic!`, puis ensuite les valeurs de retour +`Result`. De plus, nous allons voir les arguments à prendre en compte +pour choisir si nous devons essayer de récupérer une erreur ou d'arrêter +l'exécution. From 7cfecb61119268c8469a28c3ca28097023467ab3 Mon Sep 17 00:00:00 2001 From: Jimskapt Date: Thu, 14 Dec 2017 19:24:52 +0100 Subject: [PATCH 03/20] Correcting keyword in ch09-00 to map translation with whose used on SUMMARY. --- second-edition/src/ch09-00-error-handling.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/second-edition/src/ch09-00-error-handling.md b/second-edition/src/ch09-00-error-handling.md index 9254702d85..4679247b2b 100644 --- a/second-edition/src/ch09-00-error-handling.md +++ b/second-edition/src/ch09-00-error-handling.md @@ -10,11 +10,11 @@ les erreurs correctement avant même que vous déployez votre code en production ! Rust classe les erreurs dans deux catégories principales : les erreurs -*récupérables* et *non récupérables*. Les erreurs récupérables se produisent +*récupérables* et *irrécupérables*. Les erreurs récupérables se produisent dans des situations dans lesquelles il est utile de signaler l'erreur à l'utilisateur et de relancer l'opération, comme par exemple une erreur lorsque un fichier n'a pas été trouvé. -Les erreurs non récupérables sont toujours liées à des bogues, comme essayer +Les erreurs irrécupérables sont toujours liées à des bogues, comme essayer d'accéder à un caractère au-delà de la fin d'un tableau. La plupart des langages de programmation ne font pas de distinction entre ces From ff25ccdc0e465127154b42b5b82ad035efc980dc Mon Sep 17 00:00:00 2001 From: Jimskapt Date: Thu, 14 Dec 2017 20:51:48 +0100 Subject: [PATCH 04/20] Translating 33% of ch09-01 in french. --- ...ch09-01-unrecoverable-errors-with-panic.md | 172 +++++++++--------- 1 file changed, 87 insertions(+), 85 deletions(-) diff --git a/second-edition/src/ch09-01-unrecoverable-errors-with-panic.md b/second-edition/src/ch09-01-unrecoverable-errors-with-panic.md index c0ba832726..a1253bd15d 100644 --- a/second-edition/src/ch09-01-unrecoverable-errors-with-panic.md +++ b/second-edition/src/ch09-01-unrecoverable-errors-with-panic.md @@ -1,33 +1,34 @@ -## Unrecoverable Errors with `panic!` - -Sometimes, bad things happen in your code, and there’s nothing you can do about -it. In these cases, Rust has the `panic!` macro. When the `panic!` macro -executes, your program will print a failure message, unwind and clean up the -stack, and then quit. The most common situation this occurs in is when a bug of -some kind has been detected, and it’s not clear to the programmer how to handle -the error. - -> ### Unwinding the Stack or Aborting in Response to a `panic!` -> -> By default, when a `panic!` occurs, the program starts *unwinding*, which -> means Rust walks back up the stack and cleans up the data from each function -> it encounters. But this walking back and cleanup is a lot of work. The -> alternative is to immediately *abort*, which ends the program without -> cleaning up. Memory that the program was using will then need to be cleaned -> up by the operating system. If in your project you need to make the resulting -> binary as small as possible, you can switch from unwinding to aborting on -> panic by adding `panic = 'abort'` to the appropriate `[profile]` sections in -> your *Cargo.toml* file. For example, if you want to abort on panic in release -> mode, add this: -> +## Erreurs Irrécupérables avec `panic!` + +Parfois, les choses se passent mal dans votre code, et vous ne pouvez rien y +faire. Dans ce cas, Rust a la macro `panic!`. Quand la macro `panic!` +s'exécute, votre programme va afficher un message d'erreur, dévide et nettoie +la stack, et ensuite ferme le programme. Le cas le plus courant au cours +duquel cela se produit est quand une bogue a été détecté, et que ce n'est pas +clair pour le développeur de savoir comment gérer cette erreur. + +> ### Dévider la stack ou abandon en réponse à un `panic!` +> Par défaut, quand un `panic!` se produit, le programme commence par +> *dévider*, ce qui veut dire que Rust retourne en arrière dans la stack et +> nettoie les données de chaque fonction qu'il trouve. Mais cette marche en +> arrière et le nettoyage demande beaucoup de ressources. L'alternative est +> d'abandonner *immédiatement* l'exécution, qui arrête le programme sans +> nettoyage. La mémoire qu'utilisait le programme va ensuite devoir être +> nettoyée par le système d'exploitation. Si dans votre projet vous avez besoin +> de construire un exécutable le plus petit possible, vous pouvez passer du +> dévidage à l'abandon lors d'un panic en ajoutant `panic = 'abort'` aux +> sections `[profile]` appropriées dans votre fichier *Cargo.toml*. Par +> exemple, si vous voulez abandonner lors d'un panic en mode relase, ajoutez +> ceci : +> > ```toml > [profile.release] > panic = 'abort' > ``` -Let’s try calling `panic!` in a simple program: +Essayons d'appeller `panic!` dans un programme simple : -Filename: src/main.rs +Fichier: src/main.rs ```rust,should_panic fn main() { @@ -35,30 +36,33 @@ fn main() { } ``` -When you run the program, you’ll see something like this: +Quand vous lancez le programme, vous allez voir quelquechose qui ressemble à +cela : ```text $ cargo run Compiling panic v0.1.0 (file:///projects/panic) Finished dev [unoptimized + debuginfo] target(s) in 0.25 secs Running `target/debug/panic` -thread 'main' panicked at 'crash and burn', src/main.rs:2:4 +thread 'main' panicked at 'crash and burn', src/main.rs:2 note: Run with `RUST_BACKTRACE=1` for a backtrace. +error: Process didn't exit successfully: `target/debug/panic` (exit code: 101) ``` -The call to `panic!` causes the error message contained in the last three -lines. The first line shows our panic message and the place in our source code -where the panic occurred: *src/main.rs:2:4* indicates that it’s the second -line, fourth character of our *src/main.rs* file. - -In this case, the line indicated is part of our code, and if we go to that -line, we see the `panic!` macro call. In other cases, the `panic!` call might -be in code that our code calls. The filename and line number reported by the -error message will be someone else’s code where the `panic!` macro is called, -not the line of our code that eventually led to the `panic!` call. We can use -the backtrace of the functions the `panic!` call came from to figure out the -part of our code that is causing the problem. We’ll discuss what a backtrace is -in more detail next. +L'utilisation de `panic!` déclenche le message d'erreur présent dans les trois +dernières lignes. La première ligne affiche le message associé au panic et +l'emplacement dans notre code source où se produit le panic : *src/main.rs:2* +indique que c'est la ligne 2 de notre fichier *src/main.rs*. + +Dans cet exemple, la ligne indiquée fait partie de notre code, et si nous +allons voir cette ligne, nous verrons l'appel à la macro `panic!`. Dans +d'autres cas, l'appel de `panic!` pourrait se produire dans du code que nôtre +code utilise. Le nom du fichier et la ligne indiquée par le message d'erreur +sera alors du code de quelqu'un d'autre où la macro `panic!` est appellée, pas +la ligne de notre code qui pourrait mener à cet appel de `panic!`. Nous pouvons +utiliser la backtrace des fonctions qui appellent le `panic!` pour comprendre +la partie de notre code qui pose problème. Nous alons maintenant parler plus en +détail de ce qu'est une backtrace. ### Using a `panic!` Backtrace @@ -80,11 +84,11 @@ fn main() { Listing 9-1: Attempting to access an element beyond the end of a vector, which will cause a `panic!` -Here, we’re attempting to access the hundredth element of our vector (which is -at index 99 because indexing starts at zero), but it has only three elements. -In this situation, Rust will panic. Using `[]` is supposed to return an -element, but if you pass an invalid index, there’s no element that Rust could -return here that would be correct. +Here, we’re attempting to access the hundredth element (hundredth as indexing +starts at zero) of our vector, but it has only three elements. In this case, +Rust will panic. Using `[]` is supposed to return an element, but if you pass +an invalid index, there’s no element that Rust could return here that would be +correct. Other languages, like C, will attempt to give you exactly what you asked for in this situation, even though it isn’t what you want: you’ll get whatever is at @@ -104,15 +108,15 @@ $ cargo run Finished dev [unoptimized + debuginfo] target(s) in 0.27 secs Running `target/debug/panic` thread 'main' panicked at 'index out of bounds: the len is 3 but the index is -99', /checkout/src/liballoc/vec.rs:1555:10 +100', /stable-dist-rustc/build/src/libcollections/vec.rs:1362 note: Run with `RUST_BACKTRACE=1` for a backtrace. error: Process didn't exit successfully: `target/debug/panic` (exit code: 101) ``` -This error points at a file we didn’t write, *vec.rs*. That’s the -implementation of `Vec` in the standard library. The code that gets run when -we use `[]` on our vector `v` is in *vec.rs*, and that is where the `panic!` is -actually happening. +This error points at a file we didn’t write, *libcollections/vec.rs*. That’s +the implementation of `Vec` in the standard library. The code that gets run +when we use `[]` on our vector `v` is in *libcollections/vec.rs*, and that is +where the `panic!` is actually happening. The next note line tells us that we can set the `RUST_BACKTRACE` environment variable to get a backtrace of exactly what happened to cause the error. A @@ -129,42 +133,40 @@ Listing 9-2 shows output similar to what you’ll see: $ RUST_BACKTRACE=1 cargo run Finished dev [unoptimized + debuginfo] target(s) in 0.0 secs Running `target/debug/panic` -thread 'main' panicked at 'index out of bounds: the len is 3 but the index is 99', /checkout/src/liballoc/vec.rs:1555:10 +thread 'main' panicked at 'index out of bounds: the len is 3 but the index is 100', /stable-dist-rustc/build/src/libcollections/vec.rs:1392 stack backtrace: - 0: std::sys::imp::backtrace::tracing::imp::unwind_backtrace - at /checkout/src/libstd/sys/unix/backtrace/tracing/gcc_s.rs:49 - 1: std::sys_common::backtrace::_print - at /checkout/src/libstd/sys_common/backtrace.rs:71 - 2: std::panicking::default_hook::{{closure}} - at /checkout/src/libstd/sys_common/backtrace.rs:60 - at /checkout/src/libstd/panicking.rs:381 - 3: std::panicking::default_hook - at /checkout/src/libstd/panicking.rs:397 - 4: std::panicking::rust_panic_with_hook - at /checkout/src/libstd/panicking.rs:611 - 5: std::panicking::begin_panic - at /checkout/src/libstd/panicking.rs:572 - 6: std::panicking::begin_panic_fmt - at /checkout/src/libstd/panicking.rs:522 - 7: rust_begin_unwind - at /checkout/src/libstd/panicking.rs:498 - 8: core::panicking::panic_fmt - at /checkout/src/libcore/panicking.rs:71 - 9: core::panicking::panic_bounds_check - at /checkout/src/libcore/panicking.rs:58 - 10: as core::ops::index::Index>::index - at /checkout/src/liballoc/vec.rs:1555 - 11: panic::main - at src/main.rs:4 - 12: __rust_maybe_catch_panic - at /checkout/src/libpanic_unwind/lib.rs:99 - 13: std::rt::lang_start - at /checkout/src/libstd/panicking.rs:459 - at /checkout/src/libstd/panic.rs:361 - at /checkout/src/libstd/rt.rs:61 - 14: main - 15: __libc_start_main - 16: + 1: 0x560ed90ec04c - std::sys::imp::backtrace::tracing::imp::write::hf33ae72d0baa11ed + at /stable-dist-rustc/build/src/libstd/sys/unix/backtrace/tracing/gcc_s.rs:42 + 2: 0x560ed90ee03e - std::panicking::default_hook::{{closure}}::h59672b733cc6a455 + at /stable-dist-rustc/build/src/libstd/panicking.rs:351 + 3: 0x560ed90edc44 - std::panicking::default_hook::h1670459d2f3f8843 + at /stable-dist-rustc/build/src/libstd/panicking.rs:367 + 4: 0x560ed90ee41b - std::panicking::rust_panic_with_hook::hcf0ddb069e7abcd7 + at /stable-dist-rustc/build/src/libstd/panicking.rs:555 + 5: 0x560ed90ee2b4 - std::panicking::begin_panic::hd6eb68e27bdf6140 + at /stable-dist-rustc/build/src/libstd/panicking.rs:517 + 6: 0x560ed90ee1d9 - std::panicking::begin_panic_fmt::abcd5965948b877f8 + at /stable-dist-rustc/build/src/libstd/panicking.rs:501 + 7: 0x560ed90ee167 - rust_begin_unwind + at /stable-dist-rustc/build/src/libstd/panicking.rs:477 + 8: 0x560ed911401d - core::panicking::panic_fmt::hc0f6d7b2c300cdd9 + at /stable-dist-rustc/build/src/libcore/panicking.rs:69 + 9: 0x560ed9113fc8 - core::panicking::panic_bounds_check::h02a4af86d01b3e96 + at /stable-dist-rustc/build/src/libcore/panicking.rs:56 + 10: 0x560ed90e71c5 - as core::ops::Index>::index::h98abcd4e2a74c41 + at /stable-dist-rustc/build/src/libcollections/vec.rs:1392 + 11: 0x560ed90e727a - panic::main::h5d6b77c20526bc35 + at /home/you/projects/panic/src/main.rs:4 + 12: 0x560ed90f5d6a - __rust_maybe_catch_panic + at /stable-dist-rustc/build/src/libpanic_unwind/lib.rs:98 + 13: 0x560ed90ee926 - std::rt::lang_start::hd7c880a37a646e81 + at /stable-dist-rustc/build/src/libstd/panicking.rs:436 + at /stable-dist-rustc/build/src/libstd/panic.rs:361 + at /stable-dist-rustc/build/src/libstd/rt.rs:57 + 14: 0x560ed90e7302 - main + 15: 0x7f0d53f16400 - __libc_start_main + 16: 0x560ed90e6659 - _start + 17: 0x0 - ``` Listing 9-2: The backtrace generated by a call to @@ -182,7 +184,7 @@ want our program to panic, the location pointed to by the first line mentioning a file we wrote is where we should start investigating to figure out how we got to this location with values that caused the panic. In Listing 9-1 where we deliberately wrote code that would panic in order to demonstrate how to use -backtraces, the way to fix the panic is to not request an element at index 99 +backtraces, the way to fix the panic is to not request an element at index 100 from a vector that only contains three items. When your code panics in the future, you’ll need to figure out what action the code is taking with what values that causes the panic and what the code should do instead. From 8f8aff27f5d66580003fceb14125eb0ddc982eba Mon Sep 17 00:00:00 2001 From: Jimskapt Date: Fri, 15 Dec 2017 20:59:41 +0100 Subject: [PATCH 05/20] Translating 69% of ch09-01 in french. --- ...ch09-01-unrecoverable-errors-with-panic.md | 81 ++++++++++--------- 1 file changed, 44 insertions(+), 37 deletions(-) diff --git a/second-edition/src/ch09-01-unrecoverable-errors-with-panic.md b/second-edition/src/ch09-01-unrecoverable-errors-with-panic.md index a1253bd15d..7b02d24710 100644 --- a/second-edition/src/ch09-01-unrecoverable-errors-with-panic.md +++ b/second-edition/src/ch09-01-unrecoverable-errors-with-panic.md @@ -64,14 +64,14 @@ utiliser la backtrace des fonctions qui appellent le `panic!` pour comprendre la partie de notre code qui pose problème. Nous alons maintenant parler plus en détail de ce qu'est une backtrace. -### Using a `panic!` Backtrace +### Utiliser la Batrace de `panic!` -Let’s look at another example to see what it’s like when a `panic!` call comes -from a library because of a bug in our code instead of from our code calling -the macro directly. Listing 9-1 has some code that attempts to access an -element by index in a vector: +Analysons un autre exemple pour voir ce qui se passe lors d'un appel de +`panic!` se produit dans un librairie à cause d'un bug dans notre code plutôt +que d'appeller la macro directent. L'entrée 9-1 montre du code qui essaye +d'accéder aux éléments d'un vector via leurs index : -Filename: src/main.rs +Fichier: src/main.rs ```rust,should_panic fn main() { @@ -81,26 +81,27 @@ fn main() { } ``` -Listing 9-1: Attempting to access an element beyond the -end of a vector, which will cause a `panic!` +Entrée 9-1: Tentative d'accéder à un élément en dehors de +la fin d'un vector, ce qui provoque un `panic!` -Here, we’re attempting to access the hundredth element (hundredth as indexing -starts at zero) of our vector, but it has only three elements. In this case, -Rust will panic. Using `[]` is supposed to return an element, but if you pass -an invalid index, there’s no element that Rust could return here that would be -correct. +Ici, nous essayons d'accéder au centième élément (centième car l'indexation +commence à zero) de notre vector, mais il a seulement trois élements. Dans ce +cas, Rust va faire un panic. Utiliser `[]` est censé retourner un élement, mais +si vous lui founissez un index invalide, Rust ne pourra pas retourner un +élement acceptable. -Other languages, like C, will attempt to give you exactly what you asked for in -this situation, even though it isn’t what you want: you’ll get whatever is at -the location in memory that would correspond to that element in the vector, -even though the memory doesn’t belong to the vector. This is called a *buffer -overread* and can lead to security vulnerabilities if an attacker is able to -manipulate the index in such a way as to read data they shouldn’t be allowed to -that is stored after the array. +Dans ce cas, d'autre languages, comme le C, vont tenter de vous donner +exactement ce que vous avez demandé, même si ce n'est pas ce que vous voulez : +vous allez récupérer quelquechose à l'emplacement mémoire demandé qui +correspond à l'élément demande démandé dans le vector, même si cette partie de +la mémoire n'appartient pas au vector. C'est ce qu'on appelle un +*buffer overread* et peut menner à une faille de sécurité si un attaquant a la +possibilité de piloter l'index de telle manière qu'il puisse lire les données +qui ne sont qui ne devraient pas être lisibles en dehors du array. -To protect your program from this sort of vulnerability, if you try to read an -element at an index that doesn’t exist, Rust will stop execution and refuse to -continue. Let’s try it and see: +Afin de protéger votre programme de ce genre de vulnérabilité, si vous essayez +de lire un élement à un index qui n'existe pas, Rust va arrêter l'exécution et +refuser de continer. Essayez et vous verrez : ```text $ cargo run @@ -113,20 +114,26 @@ note: Run with `RUST_BACKTRACE=1` for a backtrace. error: Process didn't exit successfully: `target/debug/panic` (exit code: 101) ``` -This error points at a file we didn’t write, *libcollections/vec.rs*. That’s -the implementation of `Vec` in the standard library. The code that gets run -when we use `[]` on our vector `v` is in *libcollections/vec.rs*, and that is -where the `panic!` is actually happening. - -The next note line tells us that we can set the `RUST_BACKTRACE` environment -variable to get a backtrace of exactly what happened to cause the error. A -*backtrace* is a list of all the functions that have been called to get to this -point. Backtraces in Rust work like they do in other languages: the key to -reading the backtrace is to start from the top and read until you see files you -wrote. That’s the spot where the problem originated. The lines above the lines -mentioning your files are code that your code called; the lines below are code -that called your code. These lines might include core Rust code, standard -library code, or crates that you’re using. Let’s try getting a backtrace: +Cette erreur se réfère à un fichier que nous n'avons pas codé, +*libcollections/vec.rs*. C'est une implémentation de `Vec` dans la librairie +standard. Le code qui est lancé quand nous utilisons `[]` sur notre vecteur `v` +est dans *libcollections/vec.rs*, et c'est ici que le `panic!` se produit. + +La ligne suivante nous informe que nous pouvons régler la variable +d'environnement `RUST_BACKTRACE` pour obtenir la backtrace de ce qui s'est +exactement passé pour mener à cette erreur. Une *backtrace* est la liste de +toutes les fonctions qui ont été appellées pour arriver jusqur'à ce point. Dans +Rust, la backtrace fonctionne comme elle le fait dans d'autres languages : le +secret pour lire la bracktrace est de commencer d'en haut et lire jusqu'a ce +que vous voyez des fichiers que vous avez écrit. C'est l'emplacement où s'est +produit le problème. Les lignes avant celle qui mentionne vos fichier +représentent le code qu'à appellé votre code; les lignes qui suivent +représentent le code qui a appellé votre code. Ces lignes peuvent être du code +de Rust, du code de la librairie standard, ou des crates que vous utilisez. +Essayons une backtrace: l'entrée 9-2 contient un retour programme similaire à +celui que vous avez provoqué : + +Let’s try getting a backtrace: Listing 9-2 shows output similar to what you’ll see: ```text From b5bf5039fdc31d0237c6aa09777995092ba149f3 Mon Sep 17 00:00:00 2001 From: Jimskapt Date: Sat, 16 Dec 2017 10:25:06 +0100 Subject: [PATCH 06/20] Finishing translating ch09-01 in french. --- ...ch09-01-unrecoverable-errors-with-panic.md | 53 ++++++++++--------- 1 file changed, 27 insertions(+), 26 deletions(-) diff --git a/second-edition/src/ch09-01-unrecoverable-errors-with-panic.md b/second-edition/src/ch09-01-unrecoverable-errors-with-panic.md index 7b02d24710..395e30ac26 100644 --- a/second-edition/src/ch09-01-unrecoverable-errors-with-panic.md +++ b/second-edition/src/ch09-01-unrecoverable-errors-with-panic.md @@ -133,9 +133,6 @@ de Rust, du code de la librairie standard, ou des crates que vous utilisez. Essayons une backtrace: l'entrée 9-2 contient un retour programme similaire à celui que vous avez provoqué : -Let’s try getting a backtrace: -Listing 9-2 shows output similar to what you’ll see: - ```text $ RUST_BACKTRACE=1 cargo run Finished dev [unoptimized + debuginfo] target(s) in 0.0 secs @@ -176,26 +173,30 @@ stack backtrace: 17: 0x0 - ``` -Listing 9-2: The backtrace generated by a call to -`panic!` displayed when the environment variable `RUST_BACKTRACE` is set - -That’s a lot of output! The exact output you see might be different depending -on your operating system and Rust version. In order to get backtraces with this -information, debug symbols must be enabled. Debug symbols are enabled by -default when using cargo build or cargo run without the --release flag, as we -have here. - -In the output in Listing 9-2, line 11 of the backtrace points to the line in -our project that’s causing the problem: *src/main.rs* in line 4. If we don’t -want our program to panic, the location pointed to by the first line mentioning -a file we wrote is where we should start investigating to figure out how we got -to this location with values that caused the panic. In Listing 9-1 where we -deliberately wrote code that would panic in order to demonstrate how to use -backtraces, the way to fix the panic is to not request an element at index 100 -from a vector that only contains three items. When your code panics in the -future, you’ll need to figure out what action the code is taking with what -values that causes the panic and what the code should do instead. - -We’ll come back to `panic!` and when we should and should not use `panic!` to -handle error conditions later in the chapter. Next, we’ll look at how to -recover from an error using `Result`. +Entrée 9-2: La backtrace générée par l'appel de `panic!` +est affichée quand la variable d'environnement `RUST_BACKTRACE` est définie + + +Cela fait beaucoup de texte ! L'exactitude de votre retour qui est affiché peut +être différent en fonction de votre système d'exploitation et votre version de +Rust. Pour avoir la backtrace avec ces informations, les instructions de +débogage doivent être activés. Ils sont activés par défaut quand on utilise +`cargo build` ou `cargo run` sans le flag --release, comme c'est le cas ici. + +Sur la sortie dans l'entrée 9-2, la ligne 11 de la backtrace nous montre la +ligne de notre projet qui provoque le problème : *src/main.rs* à la ligne 4. Si +nous ne voulons pas que notre programme fasse un panic, l'emplacement cité par +la première ligne qui mentionne le code que nous avons écrit est le premier +endroit où nous devrions investiguer pour trouver les valeurs qui ont provoqué +ce panic. Dans l'entrée 9-1 où nous avons délibérément écrit du code qui fait +un panic dans le but de montrer comment nous utilisons les backtrace, la +solution pour ne pas provoquer de panic est de ne pas demander l'élement à +l'index 100 d'un vecteur quand il en contient seulement trois. A l'avenir quand +votre code provoquera des panic, vous aurez besoin de prendre des dispositions +dans votre code avec les valeurs qui provoquent un panic et de coder quoi faire +à la place. + +Nous reviendrons sur le cas du `panic!` et sur les cas où nous devrions et ne +devrions pas utiliser `panic!` pour gérer les conditions d'erreur plus tard +dans ce chapitre. Maintenant, nous allons voir comment gérer une erreur qui +utilise `Result`. From 92e24c7058c6e7a9e378793809455c9dd18a3327 Mon Sep 17 00:00:00 2001 From: Jimskapt Date: Sat, 16 Dec 2017 10:37:47 +0100 Subject: [PATCH 07/20] Typo-fixing on ch09-01. --- ...ch09-01-unrecoverable-errors-with-panic.md | 58 +++++++++---------- 1 file changed, 29 insertions(+), 29 deletions(-) diff --git a/second-edition/src/ch09-01-unrecoverable-errors-with-panic.md b/second-edition/src/ch09-01-unrecoverable-errors-with-panic.md index 395e30ac26..e52c0a8b41 100644 --- a/second-edition/src/ch09-01-unrecoverable-errors-with-panic.md +++ b/second-edition/src/ch09-01-unrecoverable-errors-with-panic.md @@ -18,7 +18,7 @@ clair pour le développeur de savoir comment gérer cette erreur. > de construire un exécutable le plus petit possible, vous pouvez passer du > dévidage à l'abandon lors d'un panic en ajoutant `panic = 'abort'` aux > sections `[profile]` appropriées dans votre fichier *Cargo.toml*. Par -> exemple, si vous voulez abandonner lors d'un panic en mode relase, ajoutez +> exemple, si vous voulez abandonner lors d'un panic en mode release, ajoutez > ceci : > > ```toml @@ -26,7 +26,7 @@ clair pour le développeur de savoir comment gérer cette erreur. > panic = 'abort' > ``` -Essayons d'appeller `panic!` dans un programme simple : +Essayons d'appeler `panic!` dans un programme simple : Fichier: src/main.rs @@ -36,7 +36,7 @@ fn main() { } ``` -Quand vous lancez le programme, vous allez voir quelquechose qui ressemble à +Quand vous lancez le programme, vous allez voir quelque chose qui ressemble à cela : ```text @@ -56,19 +56,19 @@ indique que c'est la ligne 2 de notre fichier *src/main.rs*. Dans cet exemple, la ligne indiquée fait partie de notre code, et si nous allons voir cette ligne, nous verrons l'appel à la macro `panic!`. Dans -d'autres cas, l'appel de `panic!` pourrait se produire dans du code que nôtre +d'autres cas, l'appel de `panic!` pourrait se produire dans du code que notre code utilise. Le nom du fichier et la ligne indiquée par le message d'erreur -sera alors du code de quelqu'un d'autre où la macro `panic!` est appellée, pas +sera alors du code de quelqu'un d'autre où la macro `panic!` est appelée, pas la ligne de notre code qui pourrait mener à cet appel de `panic!`. Nous pouvons utiliser la backtrace des fonctions qui appellent le `panic!` pour comprendre -la partie de notre code qui pose problème. Nous alons maintenant parler plus en -détail de ce qu'est une backtrace. +la partie de notre code qui pose problème. Nous allons maintenant parler plus +en détail de ce qu'est une backtrace. ### Utiliser la Batrace de `panic!` Analysons un autre exemple pour voir ce qui se passe lors d'un appel de `panic!` se produit dans un librairie à cause d'un bug dans notre code plutôt -que d'appeller la macro directent. L'entrée 9-1 montre du code qui essaye +que d'appeler la macro directent. L'entrée 9-1 montre du code qui essaye d'accéder aux éléments d'un vector via leurs index : Fichier: src/main.rs @@ -85,23 +85,23 @@ fn main() { la fin d'un vector, ce qui provoque un `panic!` Ici, nous essayons d'accéder au centième élément (centième car l'indexation -commence à zero) de notre vector, mais il a seulement trois élements. Dans ce -cas, Rust va faire un panic. Utiliser `[]` est censé retourner un élement, mais -si vous lui founissez un index invalide, Rust ne pourra pas retourner un -élement acceptable. +commence à zero) de notre vector, mais il a seulement trois éléments. Dans ce +cas, Rust va faire un panic. Utiliser `[]` est censé retourner un élément, mais +si vous lui fournissez un index invalide, Rust ne pourra pas retourner un +élément acceptable. -Dans ce cas, d'autre languages, comme le C, vont tenter de vous donner +Dans ce cas, d'autres languages, comme le C, vont tenter de vous donner exactement ce que vous avez demandé, même si ce n'est pas ce que vous voulez : -vous allez récupérer quelquechose à l'emplacement mémoire demandé qui -correspond à l'élément demande démandé dans le vector, même si cette partie de -la mémoire n'appartient pas au vector. C'est ce qu'on appelle un -*buffer overread* et peut menner à une faille de sécurité si un attaquant a la -possibilité de piloter l'index de telle manière qu'il puisse lire les données -qui ne sont qui ne devraient pas être lisibles en dehors du array. +vous allez récupérer quelque chose à l'emplacement mémoire demandée qui +correspond à l'élément démandé dans le vector, même si cette partie de la +mémoire n'appartient pas au vector. C'est ce qu'on appelle un *buffer overread* +et peut mener à une faille de sécurité si un attaquant à la possibilité de +piloter l'index de telle manière qu'il puisse lire les données qui ne devraient +pas être lisibles en dehors du array. Afin de protéger votre programme de ce genre de vulnérabilité, si vous essayez -de lire un élement à un index qui n'existe pas, Rust va arrêter l'exécution et -refuser de continer. Essayez et vous verrez : +de lire un élément à un index qui n'existe pas, Rust va arrêter l'exécution et +refuser de continuer. Essayez et vous verrez : ```text $ cargo run @@ -122,13 +122,13 @@ est dans *libcollections/vec.rs*, et c'est ici que le `panic!` se produit. La ligne suivante nous informe que nous pouvons régler la variable d'environnement `RUST_BACKTRACE` pour obtenir la backtrace de ce qui s'est exactement passé pour mener à cette erreur. Une *backtrace* est la liste de -toutes les fonctions qui ont été appellées pour arriver jusqur'à ce point. Dans -Rust, la backtrace fonctionne comme elle le fait dans d'autres languages : le -secret pour lire la bracktrace est de commencer d'en haut et lire jusqu'a ce -que vous voyez des fichiers que vous avez écrit. C'est l'emplacement où s'est +toutes les fonctions qui ont été appelées pour arriver jusqu'à ce point. Dans +Rust, la backtrace fonctionne comme elle le fait dans d'autres langages : le +secret pour lire la bracktrace est de commencer d'en haut et lire jusqu'à ce +que vous voyez les fichiers que vous avez écrit. C'est l'emplacement où s'est produit le problème. Les lignes avant celle qui mentionne vos fichier -représentent le code qu'à appellé votre code; les lignes qui suivent -représentent le code qui a appellé votre code. Ces lignes peuvent être du code +représentent le code qu'à appelé votre code; les lignes qui suivent +représentent le code qui a appelé votre code. Ces lignes peuvent être du code de Rust, du code de la librairie standard, ou des crates que vous utilisez. Essayons une backtrace: l'entrée 9-2 contient un retour programme similaire à celui que vous avez provoqué : @@ -180,7 +180,7 @@ est affichée quand la variable d'environnement `RUST_BACKTRACE` est définie Cela fait beaucoup de texte ! L'exactitude de votre retour qui est affiché peut être différent en fonction de votre système d'exploitation et votre version de Rust. Pour avoir la backtrace avec ces informations, les instructions de -débogage doivent être activés. Ils sont activés par défaut quand on utilise +déboguage doivent être activés. Ils sont activés par défaut quand on utilise `cargo build` ou `cargo run` sans le flag --release, comme c'est le cas ici. Sur la sortie dans l'entrée 9-2, la ligne 11 de la backtrace nous montre la @@ -190,7 +190,7 @@ la première ligne qui mentionne le code que nous avons écrit est le premier endroit où nous devrions investiguer pour trouver les valeurs qui ont provoqué ce panic. Dans l'entrée 9-1 où nous avons délibérément écrit du code qui fait un panic dans le but de montrer comment nous utilisons les backtrace, la -solution pour ne pas provoquer de panic est de ne pas demander l'élement à +solution pour ne pas provoquer de panic est de ne pas demander l'élément à l'index 100 d'un vecteur quand il en contient seulement trois. A l'avenir quand votre code provoquera des panic, vous aurez besoin de prendre des dispositions dans votre code avec les valeurs qui provoquent un panic et de coder quoi faire From 8b7e22139d9c14387ea023ec437a59fc2c338306 Mon Sep 17 00:00:00 2001 From: Jimskapt Date: Sun, 17 Dec 2017 19:50:47 +0100 Subject: [PATCH 08/20] Translating 16% of ch09-02 in french. --- .../ch09-02-recoverable-errors-with-result.md | 106 +++++++++--------- 1 file changed, 56 insertions(+), 50 deletions(-) diff --git a/second-edition/src/ch09-02-recoverable-errors-with-result.md b/second-edition/src/ch09-02-recoverable-errors-with-result.md index 52e0a689f2..a0b9b95ca8 100644 --- a/second-edition/src/ch09-02-recoverable-errors-with-result.md +++ b/second-edition/src/ch09-02-recoverable-errors-with-result.md @@ -1,16 +1,17 @@ -## Recoverable Errors with `Result` +## Erreurs récupérables avec `Result` -Most errors aren’t serious enough to require the program to stop entirely. -Sometimes, when a function fails, it’s for a reason that we can easily -interpret and respond to. For example, if we try to open a file and that -operation fails because the file doesn’t exist, we might want to create the -file instead of terminating the process. +La plupart des erreurs ne sont pas assez grave au point d'arrêter complètement +le programme. Parfois, quand une fonction échoue, c'est pour une raison que +nous pouvons facilement comprendre et réagir en conséquence. Par exemple, si +nous essayons d'ouvrir un fichier et que l'opération échoue parce que le +fichier n'existe pas, nous pourrions créer le fichier plutôt que d'arrêter le +processus. -Recall from “[Handling Potential Failure with the `Result` -Type][handle_failure]” in Chapter 2 that the `Result` enum is -defined as having two variants, `Ok` and `Err`, as follows: +Souvenez-vous dans le Chapitre 2 dans la section “[Gérer les potentielles +erreurs avec `Result`][handle_failure]” quand le enum `Rust` est +défini selon deux variantes, `Ok` et `Err`, comme ci-dessous : -[handle_failure]: ch02-00-guessing-game-tutorial.html#handling-potential-failure-with-the-result-type +[handle_failure]: ch02-00-guessing-game-tutorial.html#gérer-les-potentielles-erreurs-avec-result ```rust enum Result { @@ -19,19 +20,20 @@ enum Result { } ``` -The `T` and `E` are generic type parameters: we’ll discuss generics in more -detail in Chapter 10. What you need to know right now is that `T` represents -the type of the value that will be returned in a success case within the `Ok` -variant, and `E` represents the type of the error that will be returned in a -failure case within the `Err` variant. Because `Result` has these generic type -parameters, we can use the `Result` type and the functions that the standard -library has defined on it in many different situations where the successful -value and error value we want to return may differ. +Le `T` et `E` sont des paramètres de type génériques : nous alons parler plus +en détail des génériques au Chapitre 10. Ce que vous avez besoin de savoir pour +le moment c'est que `T` représente le type de valeur nichée dans la variante +`Ok` qui sera retournée dans le cas d'un succès, et `E` représente le type +d'erreur nichée dans la variante `Err` qui sera retournée dans le cas d'un +échec. Parce que `Result` a ces types de paramètres génériques, nous pouvons +utiliser le type `Result` et les fonctions définies dans la librairie standard +qui l'utilisent dans différentes situations où les valeurs en cas de succès et +les valeurs en cas d'erreur que nous attendons en retour peuvent différer. -Let’s call a function that returns a `Result` value because the function could -fail: in Listing 9-3 we try to open a file: +Utilisons une fonction qui retourne une valeur de type `Result` car la fonction +peut échouer : dans l'entrée 9-3 nous essayons d'ouvrir un fichier : -Filename: src/main.rs +Fichier : src/main.rs ```rust use std::fs::File; @@ -41,21 +43,22 @@ fn main() { } ``` -Listing 9-3: Opening a file +Entrée 9-3 : Ouvrir un fichier -How do we know `File::open` returns a `Result`? We could look at the standard -library API documentation, or we could ask the compiler! If we give `f` a type -annotation of a type that we know the return type of the function is *not* and -then we try to compile the code, the compiler will tell us that the types don’t -match. The error message will then tell us what the type of `f` *is*. Let’s try -it: we know that the return type of `File::open` isn’t of type `u32`, so let’s -change the `let f` statement to this: +Comment nous savons que `File::open` retourne un `Result` ? Nous pouvons +regarder la documentation de l'API et de la librairie standard, ou nous pouvons +demander au compilateur ! Si nous affectons un type à `f` dont nous savons que +le type de retour de la fonction n'est *pas* correcte et puis que nous essayons +de compiler le code, le compilateur va nous dire que les types ne coïncident +pas. Le message d'erreur va ensuite nous dire de quel type `f` *est*. Essayons +cela : nous savons que le retour de `File::open` n'est pas du type `u32`, alors +essayons de changer l'instruction `let f` comme ceci : ```rust,ignore let f: u32 = File::open("hello.txt"); ``` -Attempting to compile now gives us the following output: +La compilation nous donne maintenant le résultat suivant : ```text error[E0308]: mismatched types @@ -66,13 +69,13 @@ error[E0308]: mismatched types `std::result::Result` | = note: expected type `u32` - found type `std::result::Result` + = note: found type `std::result::Result` ``` -This tells us the return type of the `File::open` function is a `Result`. -The generic parameter `T` has been filled in here with the type of the success -value, `std::fs::File`, which is a file handle. The type of `E` used in the -error value is `std::io::Error`. +Cela nous dit que type de retour de la fonction `File::open` est un +`Result`. Le paramètre générique `T` a été remplacé dans ce cas par le +type en cas de succès, `std::fs::File`, qui est un manipulateur de fichier. Le +type de `E` utilisé pour la valeur d'erreur est `std::io::Error`. This return type means the call to `File::open` might succeed and return to us a file handle that we can read from or write to. The function call also might @@ -233,7 +236,7 @@ the `panic!` call that the `unwrap` method makes: ```text thread 'main' panicked at 'called `Result::unwrap()` on an `Err` value: Error { repr: Os { code: 2, message: "No such file or directory" } }', -src/libcore/result.rs:906:4 +/stable-dist-rustc/build/src/libcore/result.rs:868 ``` Another method, `expect`, which is similar to `unwrap`, lets us also choose the @@ -258,7 +261,8 @@ will be the parameter that we pass to `expect`, rather than the default ```text thread 'main' panicked at 'Failed to open hello.txt: Error { repr: Os { code: -2, message: "No such file or directory" } }', src/libcore/result.rs:906:4 +2, message: "No such file or directory" } }', +/stable-dist-rustc/build/src/libcore/result.rs:868 ``` Because this error message starts with the text we specified, `Failed to open @@ -383,16 +387,18 @@ is an `Err`, the value inside the `Err` will be returned from the whole function as if we had used the `return` keyword so the error value gets propagated to the calling code. -There is a difference between what the `match` expression from Listing 9-6 and -the question mark operator do: error values used with `?` go through the `from` -function, defined in the `From` trait in the standard library, which is used to -convert errors from one type into another. When the question mark calls the -`from` function, the error type received is converted into the error type -defined in the return type of the current function. This is useful when a -function returns one error type to represent all the ways a function might -fail, even if parts might fail for many different reasons. As long as each -error type implements the `from` function to define how to convert itself to -the returned error type, the question mark operator takes care of the +The one difference between the `match` expression from Listing 9-6 and what the +question mark operator does is that when using the question mark operator, +error values go through the `from` function defined in the `From` trait in the +standard library. Many error types implement the `from` function to convert an +error of one type into an error of another type. When used by the question mark +operator, the call to the `from` function converts the error type that the +question mark operator gets into the error type defined in the return type of +the current function that we’re using `?` in. This is useful when parts of a +function might fail for many different reasons, but the function returns one +error type that represents all the ways the function might fail. As long as +each error type implements the `from` function to define how to convert itself +to the returned error type, the question mark operator takes care of the conversion automatically. In the context of Listing 9-7, the `?` at the end of the `File::open` call will @@ -455,14 +461,14 @@ fn main() { When we compile this code, we get the following error message: ```text -error[E0277]: the trait bound `(): std::ops::Try` is not satisfied +error[E0277]: the `?` operator can only be used in a function that returns +`Result` (or another type that implements `std::ops::Try`) --> src/main.rs:4:13 | 4 | let f = File::open("hello.txt")?; | ------------------------ | | - | the `?` operator can only be used in a function that returns - `Result` (or another type that implements `std::ops::Try`) + | cannot use the `?` operator in a function that returns `()` | in this macro invocation | = help: the trait `std::ops::Try` is not implemented for `()` From 2f6a51d70ab80623c1d09888655f27d704de6144 Mon Sep 17 00:00:00 2001 From: Jimskapt Date: Tue, 19 Dec 2017 20:52:32 +0100 Subject: [PATCH 09/20] Translating 38% of ch09-02 in french. --- .../ch09-02-recoverable-errors-with-result.md | 90 ++++++++++--------- 1 file changed, 47 insertions(+), 43 deletions(-) diff --git a/second-edition/src/ch09-02-recoverable-errors-with-result.md b/second-edition/src/ch09-02-recoverable-errors-with-result.md index a0b9b95ca8..b2f90902b4 100644 --- a/second-edition/src/ch09-02-recoverable-errors-with-result.md +++ b/second-edition/src/ch09-02-recoverable-errors-with-result.md @@ -77,25 +77,26 @@ Cela nous dit que type de retour de la fonction `File::open` est un type en cas de succès, `std::fs::File`, qui est un manipulateur de fichier. Le type de `E` utilisé pour la valeur d'erreur est `std::io::Error`. -This return type means the call to `File::open` might succeed and return to us -a file handle that we can read from or write to. The function call also might -fail: for example, the file might not exist or we might not have permission to -access the file. The `File::open` function needs to have a way to tell us -whether it succeeded or failed and at the same time give us either the file -handle or error information. This information is exactly what the `Result` enum -conveys. - -In the case where `File::open` succeeds, the value we will have in the variable -`f` will be an instance of `Ok` that contains a file handle. In the case where -it fails, the value in `f` will be an instance of `Err` that contains more -information about the kind of error that happened. - -We need to add to the code in Listing 9-3 to take different actions depending -on the value `File::open` returned. Listing 9-4 shows one way to handle the -`Result` using a basic tool: the `match` expression that we discussed in -Chapter 6. +Ce type de retour veut dire que l'appel à `File::open` peut réussir et nous +retourner un manipulateur de fichier qui peut le lire ou l'écrire. +L'utilisation de cette fonction peut aussi échouer : par exemple, le fichier +peut ne pas exister ou nous n'avons pas le droit d'accéder au fichier. La +fonction `File::open` doit avoir un moyen de nous dire si son utilisation a +réussi ou échoué et en même temps nous fournir soit le manipulateur de fichier +soit des informations sur l'erreur. C'est exactement ces informations que le +enum `Result` nous transmet. + +Dans le cas où `File::open` réussit, la valeur que nous aurons dans la variable +`f` sera une instance de `Ok` qui contiendra un manipulateur de fichier. Dans +le cas où cela échoue, la valeur dans `f` sera une instance de `Err` qui +contiendra plus d'information sur le type d'erreur qui a eu lieu. + +Nous avons besoin d'ajouter différentes actions dans le code de l'entrée 9-3 en +fonction de la valeur que `File::open` a retourné. L'entrée 9-4 montre une +façon de gérer `Result` en utilisant un outil basique : l'expression `match` +que nous avons abordé au Chapitre 6. -Filename: src/main.rs +Fichier : src/main.rs ```rust,should_panic use std::fs::File; @@ -112,41 +113,44 @@ fn main() { } ``` -Listing 9-4: Using a `match` expression to handle the -`Result` variants we might have +Entrée 9-4: Utilisation de l'expression `match` pour +gérer les variantes que `Result` pourrait retourner. -Note that, like the `Option` enum, the `Result` enum and its variants have been -imported in the prelude, so we don’t need to specify `Result::` before the `Ok` -and `Err` variants in the `match` arms. +Veuillez noter que, comme l'enum `Option`, l'enum `Result` et ses variantes ont +été importés dans le prelude, donc vous n'avez pas besoin de préciser +`Result::` avant les variantes `Ok` et `Err` dans le bloc du `match`. -Here we tell Rust that when the result is `Ok`, return the inner `file` value -out of the `Ok` variant, and we then assign that file handle value to the -variable `f`. After the `match`, we can then use the file handle for reading or -writing. +Ici nous indiquons à Rust que quand le resultat est `Ok`, il faut sortir la +valeur `file` de la variante `Ok`, et nous assignons ensuite cette valeur à la +variable `f`. Après le `match`, nous pourrons ensuite utiliser le manipulateur +de fichier pour lire ou écrire. -The other arm of the `match` handles the case where we get an `Err` value from -`File::open`. In this example, we’ve chosen to call the `panic!` macro. If -there’s no file named *hello.txt* in our current directory and we run this -code, we’ll see the following output from the `panic!` macro: +L'autre partie du bloc `match` gère le cas où nous obtenons un `Err` de +l'appel à `File::open`. Dans cet exemple, nous avons choisi d'utiliser la macro +`panic!`. S'il n'y a pas de fichier qui s'appelle *hello.txt* dans notre +répertoire actuel et que nous exécutons ce code, nous allons voir le texte +suivant suite à l'appel de la macro `panic!` : ```text thread 'main' panicked at 'There was a problem opening the file: Error { repr: Os { code: 2, message: "No such file or directory" } }', src/main.rs:9:12 ``` -As usual, this output tells us exactly what has gone wrong. +Comme d'habitude, ce texte nous dit avec précision ce qui s'est mal passé. -### Matching on Different Errors +### Tester les différentes erreurs -The code in Listing 9-4 will `panic!` no matter the reason that `File::open` -failed. What we want to do instead is take different actions for different -failure reasons: if `File::open` failed because the file doesn’t exist, we want -to create the file and return the handle to the new file. If `File::open` -failed for any other reason, for example because we didn’t have permission to -open the file, we still want the code to `panic!` in the same way as it did in -Listing 9-4. Look at Listing 9-5, which adds another arm to the `match`: +Le code dans l'entrée 9-4 va faire un `panic!`, peut importe la raison lorsque +`File::open` échoue. Ce que nous voudrions plutôt faire est de régir +différemment en fonction des cas d'erreurs : si `File::open` a échoué parce que +n'existe pas, nous voulons créer le fichier et renvoyer un manipulateur de +fichier pour ce nouveau fichier. Si `File::open` échoue pour toute autre +raison, par exemple si nous n'avons pas l'autorisation d'ouvrir le fichier, +nous voulons quand même que le code fasse un `panic!` de la même manière qu'il +l'a fait dans l'entrée 9-4. Dans l'entrée 9-5, nous avons ajouté un nouveau cas +au bloc `match` : -Filename: src/main.rs +Fichier : src/main.rs @@ -181,8 +185,8 @@ fn main() { } ``` -Listing 9-5: Handling different kinds of errors in -different ways +Entrée 9-5 : Gestion des différents cas d'erreurs de +avec des actions différentes. The type of the value that `File::open` returns inside the `Err` variant is `io::Error`, which is a struct provided by the standard library. This struct From a76f28eaec4dbb6ec143495ff19aa6b641145c4f Mon Sep 17 00:00:00 2001 From: Jimskapt Date: Fri, 22 Dec 2017 17:58:37 +0100 Subject: [PATCH 10/20] Translating 58% of ch09-02 in french. --- .../ch09-02-recoverable-errors-with-result.md | 115 ++++++++++-------- 1 file changed, 62 insertions(+), 53 deletions(-) diff --git a/second-edition/src/ch09-02-recoverable-errors-with-result.md b/second-edition/src/ch09-02-recoverable-errors-with-result.md index b2f90902b4..1f5acd4ea5 100644 --- a/second-edition/src/ch09-02-recoverable-errors-with-result.md +++ b/second-edition/src/ch09-02-recoverable-errors-with-result.md @@ -188,43 +188,49 @@ fn main() { Entrée 9-5 : Gestion des différents cas d'erreurs de avec des actions différentes. -The type of the value that `File::open` returns inside the `Err` variant is -`io::Error`, which is a struct provided by the standard library. This struct -has a method `kind` that we can call to get an `io::ErrorKind` value. -`io::ErrorKind` is an enum provided by the standard library that has variants -representing the different kinds of errors that might result from an `io` -operation. The variant we want to use is `ErrorKind::NotFound`, which indicates -the file we’re trying to open doesn’t exist yet. - -The condition `if error.kind() == ErrorKind::NotFound` is called a *match -guard*: it’s an extra condition on a `match` arm that further refines the arm’s -pattern. This condition must be true for that arm’s code to be run; otherwise, -the pattern matching will move on to consider the next arm in the `match`. The -`ref` in the pattern is needed so `error` is not moved into the guard condition -but is merely referenced by it. The reason `ref` is used to take a reference in -a pattern instead of `&` will be covered in detail in Chapter 18. In short, in -the context of a pattern, `&` matches a reference and gives us its value, but -`ref` matches a value and gives us a reference to it. - -The condition we want to check in the match guard is whether the value returned -by `error.kind()` is the `NotFound` variant of the `ErrorKind` enum. If it is, -we try to create the file with `File::create`. However, because `File::create` -could also fail, we need to add an inner `match` statement as well. When the -file can’t be opened, a different error message will be printed. The last arm -of the outer `match` stays the same so the program panics on any error besides -the missing file error. - -### Shortcuts for Panic on Error: `unwrap` and `expect` - -Using `match` works well enough, but it can be a bit verbose and doesn’t always -communicate intent well. The `Result` type has many helper methods -defined on it to do various tasks. One of those methods, called `unwrap`, is a -shortcut method that is implemented just like the `match` statement we wrote in -Listing 9-4. If the `Result` value is the `Ok` variant, `unwrap` will return -the value inside the `Ok`. If the `Result` is the `Err` variant, `unwrap` will -call the `panic!` macro for us. Here is an example of `unwrap` in action: +La valeur de retour de `File::open` nichée dans la variante `Err` est de type +`io::Error`, ce qui est un struct fourni par la librairie standard. Ce struct +a une méthode `kind` que nous pouvons utiliser pour obtenir un retour de type +`io::ErrorKind`. +`io::ErrorKind` est un enum fourni lui aussi par la librairie standard qui a +des variantes qui représentent différents types d'erreurs qui pourraient +résulter d'une opération dans le module `io`. La variante que nous voulons +utiliser est `ErrorKind::NotFound`, qui nous informe que le fichier que nous +essayons d'ouvrir n'existe pas encore. + +La condition `if error.kind() == ErrorKind::NotFound` est ce qu'ont appelle un +*match guard* : c'est une condition supplémentaire sur une branche d'un bloc +`match` qui raffine le pattern d'une branche. Cette condition doit être valide +pour que le code de cette branche soit exécuté; autrement, le pattern matching +s'orientera sur la branche suivante dans le `match`. ** (TODO) The `ref` in the +pattern is needed so `error` is not moved into the guard condition but is +merely referenced by it.** La raison pour la quelle `ref` est utilisé pour +stocker une référence dans le pattern plutôt que un `&` va être expliquée en +détails dans le Chapitre 18. Pour faire court, dans le cas d'un pattern, `&` +est associé à une référence et nous retourne sa valeur, mais `ref` associe une +valeur et nous donne une référence vers elle. + +Le cas que nous voulons vérifier dans le match guard est lorsque la valeur +retournée par `error.kind()` est la variante de `NotFound` de l'enum +`ErrorKind`. Si c'est le cas, nous essayons de créer le fichier avec +`File::create`. Cependant, parce que `File::create` peut aussi échouer, nous +avons besoin d'ajouter a nouveau un `match` à l'intérieur du bloc. Quand le +fichier ne peut pas être ouvert, un message d'erreur différent sera affiché. La +dernière branche du `match` principal reste identique donc le programme fait un +panic sur toute autre erreur que celle du fichier inexistant. + +### Raccourci pour faire un Panic sur une erreur : `unwrap` et `expect` + +L'utilisation de `match` fonctionne assez bien, mais il peut être un peux +verbeux et ne communique pas forcément comme il le faut. Le type `Result` +a de nombreuses méthodes pour nous aider qui lui on été définies pour faire +plusieurs choses. Une de ces méthodes, qu'on appelle `unwrap`, a été implémenté +comme le `match` que nous avons écris dans l'entrée 9-4 : si la valeur de +`Result` est une variante de `Ok`, `unwrap` va retourner la valeur dans le +`Ok`, et si le `Result` est une variante de `Err`, `unwrap` va appeller la +macro `panic!` pour nous. Voici un example de `unwrap` à l'action : -Filename: src/main.rs +Fichier : src/main.rs ```rust,should_panic use std::fs::File; @@ -234,8 +240,8 @@ fn main() { } ``` -If we run this code without a *hello.txt* file, we’ll see an error message from -the `panic!` call that the `unwrap` method makes: +Si nous exécutons ce code sans le fichier *hello.txt*, nous allons voir un +message d'erreur d'un appel à `panic!` que la méthode `unwrap` a fait : ```text thread 'main' panicked at 'called `Result::unwrap()` on an `Err` value: Error { @@ -243,12 +249,13 @@ repr: Os { code: 2, message: "No such file or directory" } }', /stable-dist-rustc/build/src/libcore/result.rs:868 ``` -Another method, `expect`, which is similar to `unwrap`, lets us also choose the -`panic!` error message. Using `expect` instead of `unwrap` and providing good -error messages can convey your intent and make tracking down the source of a -panic easier. The syntax of `expect` looks like this: +L'autre méthode, `expect`, qui est similaire à `unwrap`, nous donne la +possibilité de choisir le message d'erreur du `panic!`. Utiliser `expect` +plutôt que `unwrap` et lui fournir des bons messages d'erreurs permet de mieux +exprimer le problème et faciliter la recherche de la source d'erreur. La +syntaxe de `expect` est la suivante : -Filename: src/main.rs +Fichier : src/main.rs ```rust,should_panic use std::fs::File; @@ -258,10 +265,11 @@ fn main() { } ``` -We use `expect` in the same way as `unwrap`: to return the file handle or call -the `panic!` macro. The error message used by `expect` in its call to `panic!` -will be the parameter that we pass to `expect`, rather than the default -`panic!` message that `unwrap` uses. Here’s what it looks like: +Nous utilisons `expect` de la même manière que `unwrap` : pour retourner le +manipulateur de fichier ou appeller la macro `panic!`. Le message d'erreur +utilisé par `expect` lors de son appel au `panic!` sera le paramètre que nous +avons donnée à `expect`, plutôt que le message par défaut de `panic!` +qu'utilise `unwrap`. Voici ce que cela donne : ```text thread 'main' panicked at 'Failed to open hello.txt: Error { repr: Os { code: @@ -269,13 +277,14 @@ thread 'main' panicked at 'Failed to open hello.txt: Error { repr: Os { code: /stable-dist-rustc/build/src/libcore/result.rs:868 ``` -Because this error message starts with the text we specified, `Failed to open -hello.txt`, it will be easier to find where in the code this error message is -coming from. If we use `unwrap` in multiple places, it can take more time to -figure out exactly which `unwrap` is causing the panic because all `unwrap` -calls that panic print the same message. +Parce que ce message d'erreur commence par le texte que nous avons précisé, +`Failed to open hello.txt`, ce sera plus facile de trouver d'où dans le code +ce message d'erreur proviens. Si nous utilisons `unwrap` dans plusieurs +endroits, cela peut prendre plus de temps de comprendre exactement quel +`unwrap` a déclanché le panic car tous les appels au `unwrap` vont afficher le +même message. -### Propagating Errors +### Propager les Erreurs When you’re writing a function whose implementation calls something that might fail, instead of handling the error within this function, you can return the From 4d9ea4f11bd75257d52dab744bae2d083f57b706 Mon Sep 17 00:00:00 2001 From: Jimskapt Date: Sat, 23 Dec 2017 21:05:28 +0100 Subject: [PATCH 11/20] Translating 78% of ch09-02 in french. --- .../ch09-02-recoverable-errors-with-result.md | 65 ++++++++++--------- 1 file changed, 33 insertions(+), 32 deletions(-) diff --git a/second-edition/src/ch09-02-recoverable-errors-with-result.md b/second-edition/src/ch09-02-recoverable-errors-with-result.md index 1f5acd4ea5..954d6bea33 100644 --- a/second-edition/src/ch09-02-recoverable-errors-with-result.md +++ b/second-edition/src/ch09-02-recoverable-errors-with-result.md @@ -31,9 +31,9 @@ qui l'utilisent dans différentes situations où les valeurs en cas de succès e les valeurs en cas d'erreur que nous attendons en retour peuvent différer. Utilisons une fonction qui retourne une valeur de type `Result` car la fonction -peut échouer : dans l'entrée 9-3 nous essayons d'ouvrir un fichier : +peut échouer : dans l'entrée 9-3 nous essayons d'ouvrir un Nom du fichier : -Fichier : src/main.rs +Nom du fichier : src/main.rs ```rust use std::fs::File; @@ -96,7 +96,7 @@ fonction de la valeur que `File::open` a retourné. L'entrée 9-4 montre une façon de gérer `Result` en utilisant un outil basique : l'expression `match` que nous avons abordé au Chapitre 6. -Fichier : src/main.rs +Nom du fichier : src/main.rs ```rust,should_panic use std::fs::File; @@ -150,7 +150,7 @@ nous voulons quand même que le code fasse un `panic!` de la même manière qu'i l'a fait dans l'entrée 9-4. Dans l'entrée 9-5, nous avons ajouté un nouveau cas au bloc `match` : -Fichier : src/main.rs +Nom du fichier : src/main.rs @@ -230,7 +230,7 @@ comme le `match` que nous avons écris dans l'entrée 9-4 : si la valeur de `Ok`, et si le `Result` est une variante de `Err`, `unwrap` va appeller la macro `panic!` pour nous. Voici un example de `unwrap` à l'action : -Fichier : src/main.rs +Nom du fichier : src/main.rs ```rust,should_panic use std::fs::File; @@ -255,7 +255,7 @@ plutôt que `unwrap` et lui fournir des bons messages d'erreurs permet de mieux exprimer le problème et faciliter la recherche de la source d'erreur. La syntaxe de `expect` est la suivante : -Fichier : src/main.rs +Nom du fichier : src/main.rs ```rust,should_panic use std::fs::File; @@ -286,18 +286,19 @@ même message. ### Propager les Erreurs -When you’re writing a function whose implementation calls something that might -fail, instead of handling the error within this function, you can return the -error to the calling code so that it can decide what to do. This is known as -*propagating* the error and gives more control to the calling code where there -might be more information or logic that dictates how the error should be -handled than what you have available in the context of your code. +Quand vous écrivez une fonction dont son implémentation utilise quelque chose +qui pourrait échouer, plutôt que de gérer l'erreur dans cette fonction, vous +pouvez retourner cette erreur au code qui l'appelle pour qu'il décide quoi +faire. C'est ce qu'on appelle *propager* l'erreur et donne ainsi plus de +pouvoir au code qui appelle la fonction où il pourrait y avoir plus +d'informations ou d'instructions pour traiter l'erreur que si c'était dans le +contexte de votre code. -For example, Listing 9-6 shows a function that reads a username from a file. If -the file doesn’t exist or can’t be read, this function will return those errors -to the code that called this function: +Par exemple, l'entrée 9-6 montre une fonction qui lit un nom d'utilisateur à +partir d'un fichier. Si le fichier n'existe pas ou ne peux pas être lu, cette +fonction va retourner ces erreurs au code qui a appellé cette fonction : -Filename: src/main.rs +Nom du fichier : src/main.rs ```rust use std::io; @@ -321,22 +322,22 @@ fn read_username_from_file() -> Result { } ``` -Listing 9-6: A function that returns errors to the -calling code using `match` - -Let’s look at the return type of the function first: `Result`. This means the function is returning a value of the type -`Result` where the generic parameter `T` has been filled in with the -concrete type `String`, and the generic type `E` has been filled in with the -concrete type `io::Error`. If this function succeeds without any problems, the -code that calls this function will receive an `Ok` value that holds a -`String`—the username that this function read from the file. If this function -encounters any problems, the code that calls this function will receive an -`Err` value that holds an instance of `io::Error` that contains more -information about what the problems were. We chose `io::Error` as the return -type of this function because that happens to be the type of the error value -returned from both of the operations we’re calling in this function’s body that -might fail: the `File::open` function and the `read_to_string` method. +Entrée 9-6 : une fonction qui retourne les erreurs au +code qui l'appelle en utilisant `match` + +Regardons d'abord le type de retour de la fonction : +`Result`. Cela signifie que la fonction retourne une valeur +de type `Result` où le paramètre générique `T` a été rempli avec le type +`String`, et le paramètre générique `E` a été rempli avec le type `io::Error`. +Si cette fonction réussi sans aucun problème, le code qui appelle cette +fonction va récupérer une valeur `Ok` qui contient un `String`, le nom +d'utilisateur que cette fonction lit dans le fichier. Si cette fonction +rencontre n'importe quel problème, le code qui appelle cette fonction va +récupérer une valeur `Err` qui contient une instance de `io::Error` qui apporte +plus d'informations sur la raison du problème. Nous avons choisi `io::Error` +comme type de retour de cette fonction parce que c'est le type d'erreur de +retour par chacune des opérations qu'on appelle dans le corps de cette fonction +qui peuvent échouer : la fonction `File::open` et la méthode `read_to_string`. The body of the function starts by calling the `File::open` function. Then we handle the `Result` value returned with a `match` similar to the `match` in From 35fa8372ca94016ad272ba3ba1e18abc0eb22758 Mon Sep 17 00:00:00 2001 From: Jimskapt Date: Sat, 23 Dec 2017 21:43:43 +0100 Subject: [PATCH 12/20] Forgot translated text in previous commit. --- .../ch09-02-recoverable-errors-with-result.md | 79 ++++++++++--------- 1 file changed, 41 insertions(+), 38 deletions(-) diff --git a/second-edition/src/ch09-02-recoverable-errors-with-result.md b/second-edition/src/ch09-02-recoverable-errors-with-result.md index 954d6bea33..38755a6296 100644 --- a/second-edition/src/ch09-02-recoverable-errors-with-result.md +++ b/second-edition/src/ch09-02-recoverable-errors-with-result.md @@ -339,43 +339,46 @@ comme type de retour de cette fonction parce que c'est le type d'erreur de retour par chacune des opérations qu'on appelle dans le corps de cette fonction qui peuvent échouer : la fonction `File::open` et la méthode `read_to_string`. -The body of the function starts by calling the `File::open` function. Then we -handle the `Result` value returned with a `match` similar to the `match` in -Listing 9-4, only instead of calling `panic!` in the `Err` case, we return -early from this function and pass the error value from `File::open` back to the -calling code as this function’s error value. If `File::open` succeeds, we store -the file handle in the variable `f` and continue. - -Then we create a new `String` in variable `s` and call the `read_to_string` -method on the file handle in `f` to read the contents of the file into `s`. The -`read_to_string` method also returns a `Result` because it might fail, even -though `File::open` succeeded. So we need another `match` to handle that -`Result`: if `read_to_string` succeeds, then our function has succeeded, and we -return the username from the file that’s now in `s` wrapped in an `Ok`. If -`read_to_string` fails, we return the error value in the same way that we -returned the error value in the `match` that handled the return value of -`File::open`. However, we don’t need to explicitly say `return`, because this -is the last expression in the function. - -The code that calls this code will then handle getting either an `Ok` value -that contains a username or an `Err` value that contains an `io::Error`. We -don’t know what the calling code will do with those values. If the calling code -gets an `Err` value, it could call `panic!` and crash the program, use a -default username, or look up the username from somewhere other than a file, for -example. We don’t have enough information on what the calling code is actually -trying to do, so we propagate all the success or error information upwards for -it to handle appropriately. - -This pattern of propagating errors is so common in Rust that Rust provides the -question mark operator `?` to make this easier. - -#### A Shortcut for Propagating Errors: `?` - -Listing 9-7 shows an implementation of `read_username_from_file` that has the -same functionality as it had in Listing 9-6, but this implementation uses the -question mark operator: +Le corps de la fonction commence par appeller la fonction `File::open`. Ensuite +nous gérons la valeur `Result` retourné, avec un `match` similaire au `match` +dans l'entrée 9-4, seulement, au lieu d'appeller `panic!` dans le cas de `Err`, +nous retournons prématurément la fonction et nous retournons la valeur d'erreur +de `File::open` au code appellant avec la valeur d'erreur de cette fonction. Si +`File::open` réussit, nous enregistrons le manipulateur de fichier dans la +variable `f` et nous continuons. + +Ensuite nous créons un nouveau `String` dans la variable `s` et nous appellons +la méthode `read_to_string` sur le manipulateur de fichier dans `f` pour lire +le contennu du fichier dans `s`. La méthode `read_to_string` retourne aussi un +`Result` parce qu'elle peut échouer, même si `File::open` réussit. Donc nous +avons un nouveau `match` pour gérer ce `Result` : si `read_to_string` réussit, +alors notre fonction a a réussi, et nous retournons le nom d'utilisateur à +partir du fichier qui est maintenant dans `s`, envelopé dans un `Ok`. Si +`read_to_string` échoue, nous retournons la valeur d'erreur de la même façon +que nous avons retourné la valeur d'erreur dans le `match` qui gèrait la valeur +de retour de `File::open`. Cependant, nous n'avons pas besoin de dire +explicitement `return`, car c'est la dernière instruction dans la fonction. + +Le code qui appelle ce code va devoir ensuite gérer soit une valeur `Ok` qui +contient le nom d'utilisateur, ou une valeur `Err` qui contient une +`io::Error`. Nous ne savons pas ce que va faire le code appellant avec ces +valeurs. Si le code appellant obtient une valeur `Err`, il peut utiliser un +`panic!` et faire planter le programme, utiliser un nom d'utilisateur par +défaut, ou chercher le nom d'utilisateur autre part que dans ce fichier, par +example. Nous n'avons n'avons pas assez d'informations sur ce que le code +appellant a l'intention de faire, donc nous remontons toutes les informations +de succès ou d'erreur vers le haut pour qu'elles soient traitées correctement. + +Cette façon de propager les erreurs est si courrant dans Rust que Rust fournit +l'opérateur du point d'interrogation `?` pour faciliter ceci. + +#### Un raccourci pour propager les erreurs : `?` + +L'entrée 9-7 montre une implémentation de `read_username_from_file` qui a les +mêmes fonctionnalités qu'elle a dans l'entrée 9-6, mais cette implémentation +utilise l'opérateur du point d'interrogation : -Filename: src/main.rs +Nom du fichier : src/main.rs ```rust use std::io; @@ -390,8 +393,8 @@ fn read_username_from_file() -> Result { } ``` -Listing 9-7: A function that returns errors to the -calling code using `?` +Entrée 9-7: une fonction qui retourne les erreurs au code +appellant en utilisant `?` The `?` placed after a `Result` value is defined to work in almost the same way as the `match` expressions we defined to handle the `Result` values in Listing From 90d75300d3eb33aa479c8e1afae8360d930784bf Mon Sep 17 00:00:00 2001 From: Jimskapt Date: Sun, 24 Dec 2017 12:24:58 +0100 Subject: [PATCH 13/20] Finishing translating ch09-02 in french. --- .../ch09-02-recoverable-errors-with-result.md | 125 +++++++++--------- 1 file changed, 65 insertions(+), 60 deletions(-) diff --git a/second-edition/src/ch09-02-recoverable-errors-with-result.md b/second-edition/src/ch09-02-recoverable-errors-with-result.md index 38755a6296..d5eff1e032 100644 --- a/second-edition/src/ch09-02-recoverable-errors-with-result.md +++ b/second-edition/src/ch09-02-recoverable-errors-with-result.md @@ -396,39 +396,40 @@ fn read_username_from_file() -> Result { Entrée 9-7: une fonction qui retourne les erreurs au code appellant en utilisant `?` -The `?` placed after a `Result` value is defined to work in almost the same way -as the `match` expressions we defined to handle the `Result` values in Listing -9-6. If the value of the `Result` is an `Ok`, the value inside the `Ok` will -get returned from this expression and the program will continue. If the value -is an `Err`, the value inside the `Err` will be returned from the whole -function as if we had used the `return` keyword so the error value gets -propagated to the calling code. - -The one difference between the `match` expression from Listing 9-6 and what the -question mark operator does is that when using the question mark operator, -error values go through the `from` function defined in the `From` trait in the -standard library. Many error types implement the `from` function to convert an -error of one type into an error of another type. When used by the question mark -operator, the call to the `from` function converts the error type that the -question mark operator gets into the error type defined in the return type of -the current function that we’re using `?` in. This is useful when parts of a -function might fail for many different reasons, but the function returns one -error type that represents all the ways the function might fail. As long as -each error type implements the `from` function to define how to convert itself -to the returned error type, the question mark operator takes care of the -conversion automatically. - -In the context of Listing 9-7, the `?` at the end of the `File::open` call will -return the value inside an `Ok` to the variable `f`. If an error occurs, `?` -will return early out of the whole function and give any `Err` value to the -calling code. The same thing applies to the `?` at the end of the -`read_to_string` call. - -The `?` eliminates a lot of boilerplate and makes this function’s -implementation simpler. We could even shorten this code further by chaining -method calls immediately after the `?` as shown in Listing 9-8: - -Filename: src/main.rs +Le `?` placé après une valeur `Result` est conçu pour fonctionner presque de la +même manière que la formule `match` que nous avons défini pour gérer les +valeurs `Result` dans l'entrée 9-6. Si la valeur de `Result` est un `Ok`, la +valeur dans le `Ok` sera retourné par cette expression et le programme +continuera. Si la valeur est une `Err`, la valeur à l'intérieur de `Err` sera +retournée par toute la fonction comme si nous avons utilisé le mot-clé `result` +de telle manière que la valeur d'erreur soit propagé au code appellant. + +La seule différence entre l'expression `match` de l'entrée 9-6 et ce que +l'opérateur point d'interrogation fait c'est que olorsque l'on utilise +l'opérateur point d'interrogation, les valeurs d'erreur passent par la fonction +`from` définie dans le trait `From` de la librairie standard. Beaucoup de types +d'erreur implémentent la fonction `from` pour convertir une erreur d'un type +vers une autre erreur d'un autre type. Quand on utilise l'opérateur point +d'interrogation, l'appel de la fonction `from` convertit le type d'erreur que +que l'opérateur point d'interrogation obtient vers le type d'erreur défini dans +le type d'erreur de la fonction actuelle où nous utilisons `?`. C'est utile +lorsque des parties de la fonction peuvent échouer pour différentes raisons, +mais que la fonction revoie un type d'erreur qui représente toutes les +possibilités d'échec de la fonction. Du moment que chaque type d'erreur +implémente la fonction `from` pour spécifier comment se convertir dans le type +d'erreur retournée, l'opérateur point d'interrogation s'occupe de faire la +conversion automatiquement. + +Dans le cas de l'entrée 9-7, le `?` à la fin de l'appel à `File::open` va +retourner la valeur à l'interieur d'un `Ok` à la variable `f`. Si une erreur +survient, `?` va retourner prématurément une valeur `Err` au code appellant. La +même chose se produira au `?` à ma fin de l'appel à `read_to_string`. + +Le `?` épargne du code et facilite l'implémentation. Nous pouvons même encore +plus raccourcir ce code en enchaînant immédiatement les appels aux méthodes +après le `?` comme le montre l'entrée 9-8 : + +Nom du fichier : src/main.rs ```rust use std::io; @@ -444,28 +445,31 @@ fn read_username_from_file() -> Result { } ``` -Listing 9-8: Chaining method calls after the question -mark operator +Entrée 9-8: enchaîner les appels aux méthodes après +l'opérateur point d'interrogation -We’ve moved the creation of the new `String` in `s` to the beginning of the -function; that part hasn’t changed. Instead of creating a variable `f`, we’ve -chained the call to `read_to_string` directly onto the result of -`File::open("hello.txt")?`. We still have a `?` at the end of the -`read_to_string` call, and we still return an `Ok` value containing the -username in `s` when both `File::open` and `read_to_string` succeed rather than -returning errors. The functionality is again the same as in Listing 9-6 and -Listing 9-7; this is just a different, more ergonomic way to write it. +Nous avons déplacé la création du nouveau `String` dans `s` au début de la +fonction; cette partie n'a pas changée. Au lieu de créer la variable `f`, nous +enchaînons dir'ectement l'appel à `read_to_string` sur le résultat de +`File::open("hello.txt")?`. Nous avons toujours le `?` à la fin de l'appel à +`read_to_string`, et nous retournons toujours une valeur `Ok` contennant le nom +d'utilisateur dans `s` quand `File::open` et `read_to_string` réussissent tous +les deux plutôt que de retourner des erreurs. Cette fonctionnalité fonctionne +toujours que dans l'entrée 9-6 et l'entrée 9-7; c'est juste une façon +différente et plus ergonomique de l'écrire. -#### `?` Can Only Be Used in Functions That Return Result +#### `?` ne peut être utilisé uniquement dans des fonctions qui retournent +`Result` -The `?` can only be used in functions that have a return type of `Result`, -because it is defined to work in the same way as the `match` expression we -defined in Listing 9-6. The part of the `match` that requires a return type of -`Result` is `return Err(e)`, so the return type of the function must be a -`Result` to be compatible with this `return`. +Le `?` peut uniquement être utilisé dans des fonctions qui ont un type de +retour `Result`, car il est défini pour fonctionner de la même manière que +l'expression `match` que nous avons défini dans l'entrée 9-6. La partie du +`match` qui nécessite un type de retour de `Result` est `return Err(e)`, donc +le type de retour de cette fonction doit être `Result` pour être compatible +avec ce `return`. -Let’s look at what happens if we use `?` in the `main` function, which you’ll -recall has a return type of `()`: +Regardons ce que ce passe si nous utilisons `?` dans la fonction `main`, dont +vous devriez vous rappeller qu'elle a un type de retour `()` : ```rust,ignore use std::fs::File; @@ -475,7 +479,7 @@ fn main() { } ``` -When we compile this code, we get the following error message: +Quand nous compilons ce code, nous obtenons le message d'erreur suivant : ```text error[E0277]: the `?` operator can only be used in a function that returns @@ -492,12 +496,13 @@ error[E0277]: the `?` operator can only be used in a function that returns = note: required by `std::ops::Try::from_error` ``` -This error points out that we’re only allowed to use the question mark operator -in a function that returns `Result`. In functions that don’t return `Result`, -when you call other functions that return `Result`, you’ll need to use a -`match` or one of the `Result` methods to handle it instead of using `?` to -potentially propagate the error to the calling code. +Cette erreur explique que nous sommes uniquement autorisés à utiliser +l'opérateur point d'interrogation dans une fonction qui retourne `Result`. Dans +des fonctions qui ne retournent pas `Result`, quand vous utilisez d'autres +fonctions qui retournent `Result`, vous avez besoin d'utiliser `match` ou une +des méthodes de `Result`pour gérer cela plutôt qu'utiliser `?` pour +potentiellement propager l'erreur au code appellant. -Now that we’ve discussed the details of calling `panic!` or returning `Result`, -let’s return to the topic of how to decide which is appropriate to use in which -cases. +Maintenant que nous avons vu les détails pour utiliser `panic!` ou retourner +`Result`, revenons sur au sujet de savoir lequel il conviens d'utiliser en +fonction des cas. From 7b89d20fdd4e08bf59e4f422fcbcd48838c155da Mon Sep 17 00:00:00 2001 From: Jimskapt Date: Sun, 24 Dec 2017 13:58:12 +0100 Subject: [PATCH 14/20] Typo-fixing on ch09-02. --- .../ch09-02-recoverable-errors-with-result.md | 123 +++++++++--------- 1 file changed, 61 insertions(+), 62 deletions(-) diff --git a/second-edition/src/ch09-02-recoverable-errors-with-result.md b/second-edition/src/ch09-02-recoverable-errors-with-result.md index d5eff1e032..549cf579f6 100644 --- a/second-edition/src/ch09-02-recoverable-errors-with-result.md +++ b/second-edition/src/ch09-02-recoverable-errors-with-result.md @@ -1,15 +1,15 @@ ## Erreurs récupérables avec `Result` -La plupart des erreurs ne sont pas assez grave au point d'arrêter complètement +La plupart des erreurs ne sont pas assez graves au point d'arrêter complètement le programme. Parfois, quand une fonction échoue, c'est pour une raison que nous pouvons facilement comprendre et réagir en conséquence. Par exemple, si nous essayons d'ouvrir un fichier et que l'opération échoue parce que le fichier n'existe pas, nous pourrions créer le fichier plutôt que d'arrêter le processus. -Souvenez-vous dans le Chapitre 2 dans la section “[Gérer les potentielles -erreurs avec `Result`][handle_failure]” quand le enum `Rust` est -défini selon deux variantes, `Ok` et `Err`, comme ci-dessous : +Souvenez-vous du Chapitre 2 dans la section “[Gérer les potentielles erreurs +avec `Result`][handle_failure]” quand le enum `Rust` est défini +selon deux variantes, `Ok` et `Err`, comme ci-dessous : [handle_failure]: ch02-00-guessing-game-tutorial.html#gérer-les-potentielles-erreurs-avec-result @@ -20,15 +20,15 @@ enum Result { } ``` -Le `T` et `E` sont des paramètres de type génériques : nous alons parler plus -en détail des génériques au Chapitre 10. Ce que vous avez besoin de savoir pour -le moment c'est que `T` représente le type de valeur nichée dans la variante -`Ok` qui sera retournée dans le cas d'un succès, et `E` représente le type -d'erreur nichée dans la variante `Err` qui sera retournée dans le cas d'un -échec. Parce que `Result` a ces types de paramètres génériques, nous pouvons -utiliser le type `Result` et les fonctions définies dans la librairie standard -qui l'utilisent dans différentes situations où les valeurs en cas de succès et -les valeurs en cas d'erreur que nous attendons en retour peuvent différer. +Le `T` et `E` sont des paramètres de type générique : nous alons parler plus en +détail des génériques au Chapitre 10. Ce que vous avez besoin de savoir pour le +moment c'est que `T` représente le type de valeur nichée dans la variante `Ok` +qui sera retournée dans le cas d'un succès, et `E` représente le type d'erreur +nichée dans la variante `Err` qui sera retournée dans le cas d'un échec. +Puisque `Result` a ces types de paramètres génériques, nous pouvons utiliser le +type `Result` et les fonctions définies dans la librairie standard qui +l'utilisent dans différentes situations où les valeurs en cas de succès et les +valeurs en cas d'erreur que nous attendons en retour peuvent différer. Utilisons une fonction qui retourne une valeur de type `Result` car la fonction peut échouer : dans l'entrée 9-3 nous essayons d'ouvrir un Nom du fichier : @@ -45,10 +45,10 @@ fn main() { Entrée 9-3 : Ouvrir un fichier -Comment nous savons que `File::open` retourne un `Result` ? Nous pouvons +Comment savons-nous que `File::open` retourne un `Result` ? Nous pouvons regarder la documentation de l'API et de la librairie standard, ou nous pouvons demander au compilateur ! Si nous affectons un type à `f` dont nous savons que -le type de retour de la fonction n'est *pas* correcte et puis que nous essayons +le type de retour de la fonction n'est *pas* correcte et puisque nous essayons de compiler le code, le compilateur va nous dire que les types ne coïncident pas. Le message d'erreur va ensuite nous dire de quel type `f` *est*. Essayons cela : nous savons que le retour de `File::open` n'est pas du type `u32`, alors @@ -80,7 +80,7 @@ type de `E` utilisé pour la valeur d'erreur est `std::io::Error`. Ce type de retour veut dire que l'appel à `File::open` peut réussir et nous retourner un manipulateur de fichier qui peut le lire ou l'écrire. L'utilisation de cette fonction peut aussi échouer : par exemple, le fichier -peut ne pas exister ou nous n'avons pas le droit d'accéder au fichier. La +peut ne pas exister, ou nous n'avons pas le droit d'accéder au fichier. La fonction `File::open` doit avoir un moyen de nous dire si son utilisation a réussi ou échoué et en même temps nous fournir soit le manipulateur de fichier soit des informations sur l'erreur. C'est exactement ces informations que le @@ -120,7 +120,7 @@ Veuillez noter que, comme l'enum `Option`, l'enum `Result` et ses variantes ont été importés dans le prelude, donc vous n'avez pas besoin de préciser `Result::` avant les variantes `Ok` et `Err` dans le bloc du `match`. -Ici nous indiquons à Rust que quand le resultat est `Ok`, il faut sortir la +Ici nous indiquons à Rust que quand le résultat est `Ok`, il faut sortir la valeur `file` de la variante `Ok`, et nous assignons ensuite cette valeur à la variable `f`. Après le `match`, nous pourrons ensuite utiliser le manipulateur de fichier pour lire ou écrire. @@ -198,13 +198,13 @@ résulter d'une opération dans le module `io`. La variante que nous voulons utiliser est `ErrorKind::NotFound`, qui nous informe que le fichier que nous essayons d'ouvrir n'existe pas encore. -La condition `if error.kind() == ErrorKind::NotFound` est ce qu'ont appelle un +La condition `if error.kind() == ErrorKind::NotFound` est ce qu'on appelle un *match guard* : c'est une condition supplémentaire sur une branche d'un bloc `match` qui raffine le pattern d'une branche. Cette condition doit être valide -pour que le code de cette branche soit exécuté; autrement, le pattern matching +pour que le code de cette branche soit exécutée; autrement, le pattern matching s'orientera sur la branche suivante dans le `match`. ** (TODO) The `ref` in the pattern is needed so `error` is not moved into the guard condition but is -merely referenced by it.** La raison pour la quelle `ref` est utilisé pour +merely referenced by it.** La raison pour laquelle `ref` est utilisé pour stocker une référence dans le pattern plutôt que un `&` va être expliquée en détails dans le Chapitre 18. Pour faire court, dans le cas d'un pattern, `&` est associé à une référence et nous retourne sa valeur, mais `ref` associe une @@ -214,21 +214,21 @@ Le cas que nous voulons vérifier dans le match guard est lorsque la valeur retournée par `error.kind()` est la variante de `NotFound` de l'enum `ErrorKind`. Si c'est le cas, nous essayons de créer le fichier avec `File::create`. Cependant, parce que `File::create` peut aussi échouer, nous -avons besoin d'ajouter a nouveau un `match` à l'intérieur du bloc. Quand le +avons besoin d'ajouter à nouveau un `match` à l'intérieur du bloc. Quand le fichier ne peut pas être ouvert, un message d'erreur différent sera affiché. La dernière branche du `match` principal reste identique donc le programme fait un panic sur toute autre erreur que celle du fichier inexistant. ### Raccourci pour faire un Panic sur une erreur : `unwrap` et `expect` -L'utilisation de `match` fonctionne assez bien, mais il peut être un peux +L'utilisation de `match` fonctionne assez bien, mais il peut être un peu verbeux et ne communique pas forcément comme il le faut. Le type `Result` -a de nombreuses méthodes pour nous aider qui lui on été définies pour faire +a de nombreuses méthodes pour nous aider qui lui ont été définies pour faire plusieurs choses. Une de ces méthodes, qu'on appelle `unwrap`, a été implémenté -comme le `match` que nous avons écris dans l'entrée 9-4 : si la valeur de +comme le `match` que nous avons écri dans l'entrée 9-4 : si la valeur de `Result` est une variante de `Ok`, `unwrap` va retourner la valeur dans le -`Ok`, et si le `Result` est une variante de `Err`, `unwrap` va appeller la -macro `panic!` pour nous. Voici un example de `unwrap` à l'action : +`Ok`, et si le `Result` est une variante de `Err`, `unwrap` va appeler la +macro `panic!` pour nous. Voici un exemple de `unwrap` à l'action : Nom du fichier : src/main.rs @@ -251,7 +251,7 @@ repr: Os { code: 2, message: "No such file or directory" } }', L'autre méthode, `expect`, qui est similaire à `unwrap`, nous donne la possibilité de choisir le message d'erreur du `panic!`. Utiliser `expect` -plutôt que `unwrap` et lui fournir des bons messages d'erreurs permet de mieux +plutôt que `unwrap` et lui fournir de bons messages d'erreurs permet de mieux exprimer le problème et faciliter la recherche de la source d'erreur. La syntaxe de `expect` est la suivante : @@ -266,9 +266,9 @@ fn main() { ``` Nous utilisons `expect` de la même manière que `unwrap` : pour retourner le -manipulateur de fichier ou appeller la macro `panic!`. Le message d'erreur +manipulateur de fichier ou appeler la macro `panic!`. Le message d'erreur utilisé par `expect` lors de son appel au `panic!` sera le paramètre que nous -avons donnée à `expect`, plutôt que le message par défaut de `panic!` +avons donné à `expect`, plutôt que le message par défaut de `panic!` qu'utilise `unwrap`. Voici ce que cela donne : ```text @@ -281,7 +281,7 @@ Parce que ce message d'erreur commence par le texte que nous avons précisé, `Failed to open hello.txt`, ce sera plus facile de trouver d'où dans le code ce message d'erreur proviens. Si nous utilisons `unwrap` dans plusieurs endroits, cela peut prendre plus de temps de comprendre exactement quel -`unwrap` a déclanché le panic car tous les appels au `unwrap` vont afficher le +`unwrap` a déclenché le panic, car tous les appels au `unwrap` vont afficher le même message. ### Propager les Erreurs @@ -296,7 +296,7 @@ contexte de votre code. Par exemple, l'entrée 9-6 montre une fonction qui lit un nom d'utilisateur à partir d'un fichier. Si le fichier n'existe pas ou ne peux pas être lu, cette -fonction va retourner ces erreurs au code qui a appellé cette fonction : +fonction va retourner ces erreurs au code qui a appelé cette fonction : Nom du fichier : src/main.rs @@ -329,7 +329,7 @@ Regardons d'abord le type de retour de la fonction : `Result`. Cela signifie que la fonction retourne une valeur de type `Result` où le paramètre générique `T` a été rempli avec le type `String`, et le paramètre générique `E` a été rempli avec le type `io::Error`. -Si cette fonction réussi sans aucun problème, le code qui appelle cette +Si cette fonction réussie sans aucun problème, le code qui appelle cette fonction va récupérer une valeur `Ok` qui contient un `String`, le nom d'utilisateur que cette fonction lit dans le fichier. Si cette fonction rencontre n'importe quel problème, le code qui appelle cette fonction va @@ -339,37 +339,37 @@ comme type de retour de cette fonction parce que c'est le type d'erreur de retour par chacune des opérations qu'on appelle dans le corps de cette fonction qui peuvent échouer : la fonction `File::open` et la méthode `read_to_string`. -Le corps de la fonction commence par appeller la fonction `File::open`. Ensuite +Le corps de la fonction commence par appeler la fonction `File::open`. Ensuite, nous gérons la valeur `Result` retourné, avec un `match` similaire au `match` -dans l'entrée 9-4, seulement, au lieu d'appeller `panic!` dans le cas de `Err`, +dans l'entrée 9-4, seulement, au lieu d'appeler `panic!` dans le cas de `Err`, nous retournons prématurément la fonction et nous retournons la valeur d'erreur -de `File::open` au code appellant avec la valeur d'erreur de cette fonction. Si +de `File::open` au code appelant avec la valeur d'erreur de cette fonction. Si `File::open` réussit, nous enregistrons le manipulateur de fichier dans la variable `f` et nous continuons. -Ensuite nous créons un nouveau `String` dans la variable `s` et nous appellons +Ensuite, nous créons un nouveau `String` dans la variable `s` et nous appelons la méthode `read_to_string` sur le manipulateur de fichier dans `f` pour lire -le contennu du fichier dans `s`. La méthode `read_to_string` retourne aussi un +le contenu du fichier dans `s`. La méthode `read_to_string` retourne aussi un `Result` parce qu'elle peut échouer, même si `File::open` réussit. Donc nous avons un nouveau `match` pour gérer ce `Result` : si `read_to_string` réussit, -alors notre fonction a a réussi, et nous retournons le nom d'utilisateur à -partir du fichier qui est maintenant dans `s`, envelopé dans un `Ok`. Si +alors notre fonction a réussi, et nous retournons le nom d'utilisateur à partir +du fichier qui est maintenant dans `s`, enveloppé dans un `Ok`. Si `read_to_string` échoue, nous retournons la valeur d'erreur de la même façon -que nous avons retourné la valeur d'erreur dans le `match` qui gèrait la valeur +que nous avons retourné la valeur d'erreur dans le `match` qui gérait la valeur de retour de `File::open`. Cependant, nous n'avons pas besoin de dire explicitement `return`, car c'est la dernière instruction dans la fonction. Le code qui appelle ce code va devoir ensuite gérer soit une valeur `Ok` qui contient le nom d'utilisateur, ou une valeur `Err` qui contient une -`io::Error`. Nous ne savons pas ce que va faire le code appellant avec ces -valeurs. Si le code appellant obtient une valeur `Err`, il peut utiliser un +`io::Error`. Nous ne savons pas ce que va faire le code appelant avec ces +valeurs. Si le code appelant obtient une valeur `Err`, il peut utiliser un `panic!` et faire planter le programme, utiliser un nom d'utilisateur par défaut, ou chercher le nom d'utilisateur autre part que dans ce fichier, par -example. Nous n'avons n'avons pas assez d'informations sur ce que le code -appellant a l'intention de faire, donc nous remontons toutes les informations -de succès ou d'erreur vers le haut pour qu'elles soient traitées correctement. +exemple. Nous n'avons pas assez d'informations sur ce que le code appelant a +l'intention de faire, donc nous remontons toutes les informations de succès ou +d'erreur vers le haut pour qu'elles soient traitées correctement. -Cette façon de propager les erreurs est si courrant dans Rust que Rust fournit +Cette façon de propager les erreurs est si courante dans Rust que Rust fournit l'opérateur du point d'interrogation `?` pour faciliter ceci. #### Un raccourci pour propager les erreurs : `?` @@ -394,25 +394,25 @@ fn read_username_from_file() -> Result { ``` Entrée 9-7: une fonction qui retourne les erreurs au code -appellant en utilisant `?` +appelant en utilisant `?` Le `?` placé après une valeur `Result` est conçu pour fonctionner presque de la même manière que la formule `match` que nous avons défini pour gérer les valeurs `Result` dans l'entrée 9-6. Si la valeur de `Result` est un `Ok`, la -valeur dans le `Ok` sera retourné par cette expression et le programme +valeur dans le `Ok` sera retournée par cette expression et le programme continuera. Si la valeur est une `Err`, la valeur à l'intérieur de `Err` sera retournée par toute la fonction comme si nous avons utilisé le mot-clé `result` -de telle manière que la valeur d'erreur soit propagé au code appellant. +de telle manière que la valeur d'erreur soit propagé au code appelant. La seule différence entre l'expression `match` de l'entrée 9-6 et ce que -l'opérateur point d'interrogation fait c'est que olorsque l'on utilise +l'opérateur point d'interrogation fait c'est que lorsque l'on utilise l'opérateur point d'interrogation, les valeurs d'erreur passent par la fonction `from` définie dans le trait `From` de la librairie standard. Beaucoup de types d'erreur implémentent la fonction `from` pour convertir une erreur d'un type vers une autre erreur d'un autre type. Quand on utilise l'opérateur point d'interrogation, l'appel de la fonction `from` convertit le type d'erreur que -que l'opérateur point d'interrogation obtient vers le type d'erreur défini dans -le type d'erreur de la fonction actuelle où nous utilisons `?`. C'est utile +l'opérateur point d'interrogation obtient vers le type d'erreur défini dans le +type d'erreur de la fonction actuelle où nous utilisons `?`. C'est utile lorsque des parties de la fonction peuvent échouer pour différentes raisons, mais que la fonction revoie un type d'erreur qui représente toutes les possibilités d'échec de la fonction. Du moment que chaque type d'erreur @@ -421,8 +421,8 @@ d'erreur retournée, l'opérateur point d'interrogation s'occupe de faire la conversion automatiquement. Dans le cas de l'entrée 9-7, le `?` à la fin de l'appel à `File::open` va -retourner la valeur à l'interieur d'un `Ok` à la variable `f`. Si une erreur -survient, `?` va retourner prématurément une valeur `Err` au code appellant. La +retourner la valeur à l'intérieur d'un `Ok` à la variable `f`. Si une erreur +survient, `?` va retourner prématurément une valeur `Err` au code appelant. La même chose se produira au `?` à ma fin de l'appel à `read_to_string`. Le `?` épargne du code et facilite l'implémentation. Nous pouvons même encore @@ -450,16 +450,15 @@ l'opérateur point d'interrogation Nous avons déplacé la création du nouveau `String` dans `s` au début de la fonction; cette partie n'a pas changée. Au lieu de créer la variable `f`, nous -enchaînons dir'ectement l'appel à `read_to_string` sur le résultat de +enchaînons directement l'appel à `read_to_string` sur le résultat de `File::open("hello.txt")?`. Nous avons toujours le `?` à la fin de l'appel à -`read_to_string`, et nous retournons toujours une valeur `Ok` contennant le nom +`read_to_string`, et nous retournons toujours une valeur `Ok` contenant le nom d'utilisateur dans `s` quand `File::open` et `read_to_string` réussissent tous les deux plutôt que de retourner des erreurs. Cette fonctionnalité fonctionne toujours que dans l'entrée 9-6 et l'entrée 9-7; c'est juste une façon différente et plus ergonomique de l'écrire. -#### `?` ne peut être utilisé uniquement dans des fonctions qui retournent -`Result` +#### `?` ne peut être utilisé que dans des fonctions qui retournent `Result` Le `?` peut uniquement être utilisé dans des fonctions qui ont un type de retour `Result`, car il est défini pour fonctionner de la même manière que @@ -469,7 +468,7 @@ le type de retour de cette fonction doit être `Result` pour être compatible avec ce `return`. Regardons ce que ce passe si nous utilisons `?` dans la fonction `main`, dont -vous devriez vous rappeller qu'elle a un type de retour `()` : +vous devriez vous rappeler qu'elle a un type de retour `()` : ```rust,ignore use std::fs::File; @@ -500,9 +499,9 @@ Cette erreur explique que nous sommes uniquement autorisés à utiliser l'opérateur point d'interrogation dans une fonction qui retourne `Result`. Dans des fonctions qui ne retournent pas `Result`, quand vous utilisez d'autres fonctions qui retournent `Result`, vous avez besoin d'utiliser `match` ou une -des méthodes de `Result`pour gérer cela plutôt qu'utiliser `?` pour -potentiellement propager l'erreur au code appellant. +des méthodes de `Result` pour gérer cela plutôt qu'utiliser `?` pour +potentiellement propager l'erreur au code appelant. Maintenant que nous avons vu les détails pour utiliser `panic!` ou retourner -`Result`, revenons sur au sujet de savoir lequel il conviens d'utiliser en +`Result`, revenons sur au sujet de savoir lequel il convient d'utiliser en fonction des cas. From ab2670d259c018dd9ff14d6f00eacf018b6a2a07 Mon Sep 17 00:00:00 2001 From: Jimskapt Date: Wed, 27 Dec 2017 07:15:28 +0100 Subject: [PATCH 15/20] Translating 17% of ch09-03 in french. --- .../src/ch09-03-to-panic-or-not-to-panic.md | 80 ++++++++++--------- 1 file changed, 42 insertions(+), 38 deletions(-) diff --git a/second-edition/src/ch09-03-to-panic-or-not-to-panic.md b/second-edition/src/ch09-03-to-panic-or-not-to-panic.md index bb710e3c1c..c453e35e78 100644 --- a/second-edition/src/ch09-03-to-panic-or-not-to-panic.md +++ b/second-edition/src/ch09-03-to-panic-or-not-to-panic.md @@ -1,42 +1,47 @@ ## To `panic!` or Not to `panic!` -So how do you decide when you should `panic!` and when you should return -`Result`? When code panics, there’s no way to recover. You could call `panic!` -for any error situation, whether there’s a possible way to recover or not, but -then you’re making the decision on behalf of the code calling your code that a -situation is unrecoverable. When you choose to return a `Result` value, you -give the calling code options rather than making the decision for it. The -calling code could choose to attempt to recover in a way that’s appropriate for -its situation, or it could decide that an `Err` value in this case is -unrecoverable, so it can call `panic!` and turn your recoverable error into an -unrecoverable one. Therefore, returning `Result` is a good default choice when -you’re defining a function that might fail. - -In a few situations it’s more appropriate to write code that panics instead of -returning a `Result`, but they are less common. Let’s explore why it’s -appropriate to panic in examples, prototype code, and tests; then in situations -where you as a human can know a method won’t fail that the compiler can’t -reason about; and conclude with some general guidelines on how to decide -whether to panic in library code. - -### Examples, Prototype Code, and Tests Are All Places it’s Perfectly Fine to Panic - -When you’re writing an example to illustrate some concept, having robust error -handling code in the example as well can make the example less clear. In -examples, it’s understood that a call to a method like `unwrap` that could -`panic!` is meant as a placeholder for the way that you’d want your application -to handle errors, which can differ based on what the rest of your code is doing. - -Similarly, the `unwrap` and `expect` methods are very handy when prototyping, -before you’re ready to decide how to handle errors. They leave clear markers in -your code for when you’re ready to make your program more robust. - -If a method call fails in a test, we’d want the whole test to fail, even if -that method isn’t the functionality under test. Because `panic!` is how a test -is marked as a failure, calling `unwrap` or `expect` is exactly what should -happen. - -### Cases When You Have More Information Than the Compiler +Donc, comment décider quand on doit faire un `panic!` et quand nous devons +retourner un `Result` ? Quand un code fait un panic, il n'y a pas de moyen de +continuer l'exécution. Vous pouriez faire appel à `panic!` pour n'importe +quelle situation d'erreur, peux importe s'il est possible de continuer +l'exécution ou non, mais alors vous prenez la décision de tout arrêter à la +place du code appelant. Quand vous choisissez de retourner une valeur `Result`, +vous donnez plus de choix au code appelant plutôt que si vous preniez des +décisions à sa place. Le code appelant peut choisir d'essayer de récupérer +l'erreur de manière appropriée à cette situation, ou il peut décider que dans +ce cas une valeur `Err` est irrécupérable, donc utiliser `panic!` et changer +votre erreur récupérable en erreur irrécupérable. Ainsi, retourner `Result` est +un bon choix par défaut quand vous construisez une fonction qui peux échouer. + +Dans quelques situations, c'est plus approprié d'écrire du code qui fait un +panic au lieu de retourner un `Result`, mais elles sont moins fréquentes. +Voyons pourquoi ils est approprié pourquoi il est plus approprié de faire un +panic dans des examples, des prototypes, et des tests; ensuite des situations +où vous savez qu'en tant qu'humain qu'une méthode ne peux pas échouer mais que +le compilateur n'a pas de raison de le faire; et nous alons conclure par +quelques lignes conductrices générales sur comment décider s'il faut paniquer +dans le code des librairies. + +### Les examples, prototypes, et les tests sont les endroit parfaits pour Panic + +Quand vous écrivez un example pour illustrer un concept, avoir un code de +gestion des erreurs très résiliente peut rendre l'exemple moins claire. Dans +les examples, il est courrant d'utiliser une méthode comme `unwrap` qui peut +faire un `panic!` qui remplace le code de gestion de l'erreur que vous +utiliseriez dans votre application, qui peux changer en fonction de ce que le +reste de votre code va faire. + +De la même manière, les méthodes `unwrap` et `expect` sont très pratiques pour +coder des prototypes, avant de décider comment gérer les erreurs. Ce sont des +indicateurs claires dans votre code pour plus tard quand vous serez prêt à +rendre votre code plus résilient aux échecs. + +Si l'appel à une méthode échoue dans un test, nous voulons que tout le test +échoue, même si cette méthode n'est pas la fonctionnalité que nous testons. +Parceque `panic!` est la manière de le marquer un échec, utiliser `unwrap` ou +`expect` est exactement ce qui est nécessaire. + +### Les cas où vous avez plus d'informations que le compilateur It would also be appropriate to call `unwrap` when you have some other logic that ensures the `Result` will have an `Ok` value, but the logic isn’t @@ -243,4 +248,3 @@ situations will make your code more reliable in the face of inevitable problems. Now that you’ve seen useful ways that the standard library uses generics with the `Option` and `Result` enums, we’ll talk about how generics work and how you can use them in your code in the next chapter. - From 56e110907e7f7acbab17097b5145358814266b2a Mon Sep 17 00:00:00 2001 From: Jimskapt Date: Thu, 28 Dec 2017 10:00:32 +0100 Subject: [PATCH 16/20] Translating 40% of ch09-03 in french. --- .../src/ch09-03-to-panic-or-not-to-panic.md | 96 ++++++++++--------- 1 file changed, 51 insertions(+), 45 deletions(-) diff --git a/second-edition/src/ch09-03-to-panic-or-not-to-panic.md b/second-edition/src/ch09-03-to-panic-or-not-to-panic.md index c453e35e78..fa05f8f301 100644 --- a/second-edition/src/ch09-03-to-panic-or-not-to-panic.md +++ b/second-edition/src/ch09-03-to-panic-or-not-to-panic.md @@ -43,14 +43,15 @@ Parceque `panic!` est la manière de le marquer un échec, utiliser `unwrap` ou ### Les cas où vous avez plus d'informations que le compilateur -It would also be appropriate to call `unwrap` when you have some other logic -that ensures the `Result` will have an `Ok` value, but the logic isn’t -something the compiler understands. You’ll still have a `Result` value that you -need to handle: whatever operation you’re calling still has the possibility of -failing in general, even though it’s logically impossible in your particular -situation. If you can ensure by manually inspecting the code that you’ll never -have an `Err` variant, it’s perfectly acceptable to call `unwrap`. Here’s an -example: +Il peut parfois être approprié d'utiliser `unwrap` quand vous avez un code +logique qui garanti que `Result` aura toujours une valeur de type `Ok`, mais +que c'est une logique que le compilateur ne comprends pas. Vous travaillez +toujours une valeur de type `Result` que vous devez gérer : quelque soit +l'instruction que vous appelez, elle a toujours la possibilité d'échouer, +même si dans ce cas particulier, c'est logiquement impossible. Si vous êtes +sûr en inspectant le code manuellement que vous n'allez jamais obtenir une +variante de `Err`, il est tout à fait acceptable d'utiliser `unwrap`. Voici un +example : ```rust use std::net::IpAddr; @@ -58,43 +59,48 @@ use std::net::IpAddr; let home: IpAddr = "127.0.0.1".parse().unwrap(); ``` -We’re creating an `IpAddr` instance by parsing a hardcoded string. We can see -that `127.0.0.1` is a valid IP address, so it’s acceptable to use `unwrap` -here. However, having a hardcoded, valid string doesn’t change the return type -of the `parse` method: we still get a `Result` value, and the compiler will -still make us handle the `Result` as if the `Err` variant is still a -possibility because the compiler isn’t smart enough to see that this string is -always a valid IP address. If the IP address string came from a user rather -than being hardcoded into the program, and therefore *did* have a possibility -of failure, we’d definitely want to handle the `Result` in a more robust way -instead. - -### Guidelines for Error Handling - -It’s advisable to have your code `panic!` when it’s possible that your code -could end up in a bad state. In this context, bad state is when some -assumption, guarantee, contract, or invariant has been broken, such as when -invalid values, contradictory values, or missing values are passed to your -code—plus one or more of the following: - -* The bad state is not something that’s *expected* to happen occasionally. -* Your code after this point needs to rely on not being in this bad state. -* There’s not a good way to encode this information in the types you use. - -If someone calls your code and passes in values that don’t make sense, the best -choice might be to `panic!` and alert the person using your library to the bug -in their code so they can fix it during development. Similarly, `panic!` is -often appropriate if you’re calling external code that is out of your control, -and it returns an invalid state that you have no way of fixing. - -When a bad state is reached, but it’s expected to happen no matter how well you -write your code, it’s still more appropriate to return a `Result` rather than -making a `panic!` call. Examples of this include a parser being given malformed -data or an HTTP request returning a status that indicates you have hit a rate -limit. In these cases, you should indicate that failure is an expected -possibility by returning a `Result` to propagate these bad states upwards so -the calling code can decide how to handle the problem. To `panic!` wouldn’t be -the best way to handle these cases. +Nous créons une instance de `IpAddr` en parsant une chaine de caractères pure. +Nous savons que `127.0.0.1` est une adresse IP valide, donc il est convenable +d'utiliser `unwrap` ici. Toutefois, avoir une chaine de caractères valide, +codée en dur ne change jamais le type de retour de la méthode `parse` : nous +obtenons toujours une valeur de type `Result`, et le compilateur va nous faire +gérer le `Result` comme si la variante `Err` est toujours probable car le +compilateur n'est pas encore suffisamment intelligent pour analyser que cette +chaine de caractères est toujours une adresse IP valide. Si le texte de +l'adresse IP provient de l'utilisateur plutôt que d'être codé en dur dans le +programme, et fait en sorte qu'il y a désormais une possibilité d'erreur, nous +devrions gérer le `Result` de manière plus résiliente désormais. + +### Recommandations pour gérer les erreurs + +Il est recommandé de faire un `panic!` dans votre code lorsqu'il s'exécute dans +de mauvaises conditions. Dans ce sens, les mauvaises conditions sont lorsque un +postulat, une garantie, un contrat ou une invariance a été rompue, comme des +valeurs invalides, contradictoires ou manquantes fournies à votre code, par un +ou plusieurs des éléments suivants : + +* Ces mauvaises conditions ne sont pas *prévues* pour surgir de temps en temps. +* Après cette instruction, votre code a besoin de ne pas être dans ces +mauvaises conditions. +* Il n'y pas de bonne façon de coder ces informations dans les types que vous +utilisez. + +Si quelqu'un utilise votre code et lui fournit des valeurs qui n'ont pas de +sens, la meilleure des choses à faire et de faire un `panic!` et avertir +le développeur de votre librairie du bogue dans leur code afin qu'il le règle +pendant la phase de développement. De la même manière, `panic!` est parfois +approprié si vous appellez un code externe dont vous n'avez pas la main dessus, +et qu'il retourne de mauvaises conditions que vous ne pouvez pas corriger. + +Lorsque les condtions sont mauvaises, mais qui est prévu que cela arrive peu +importe la façon que vous écrivez votre code, il est plus aproprié de retourner +un `Result` plutôt que faire appel à `panic!`. Il peut s'agir par exemple d'un +un parseur qui reçoit des données éronnées, ou une requête HTTP qui renvoit un +statut qui indique que vous avez atteint une limite de débit. Dans ce cas, vous +devriez que cet échec est un possibilité en retournant un `Result` pour +propager ces mauvaises conditions vers le haut pour que le code appelant puisse +décider quoi faire pour gérer le problème. Faire un `panic!` ne serait pas la +manière la approprié ici pour gérer ces problèmes. When your code performs operations on values, your code should verify the values are valid first, and `panic!` if the values aren’t valid. This is mostly From 759ae48dd593e2497815ea862d44473d6df2fa2a Mon Sep 17 00:00:00 2001 From: Jimskapt Date: Sat, 30 Dec 2017 17:33:26 +0100 Subject: [PATCH 17/20] Translating 52% of ch09-03 in french. --- .../src/ch09-03-to-panic-or-not-to-panic.md | 62 ++++++++++--------- 1 file changed, 33 insertions(+), 29 deletions(-) diff --git a/second-edition/src/ch09-03-to-panic-or-not-to-panic.md b/second-edition/src/ch09-03-to-panic-or-not-to-panic.md index fa05f8f301..9c8e89dbb5 100644 --- a/second-edition/src/ch09-03-to-panic-or-not-to-panic.md +++ b/second-edition/src/ch09-03-to-panic-or-not-to-panic.md @@ -102,35 +102,39 @@ propager ces mauvaises conditions vers le haut pour que le code appelant puisse décider quoi faire pour gérer le problème. Faire un `panic!` ne serait pas la manière la approprié ici pour gérer ces problèmes. -When your code performs operations on values, your code should verify the -values are valid first, and `panic!` if the values aren’t valid. This is mostly -for safety reasons: attempting to operate on invalid data can expose your code -to vulnerabilities. This is the main reason the standard library will `panic!` -if you attempt an out-of-bounds memory access: trying to access memory that -doesn’t belong to the current data structure is a common security problem. -Functions often have *contracts*: their behavior is only guaranteed if the -inputs meet particular requirements. Panicking when the contract is violated -makes sense because a contract violation always indicates a caller-side bug, -and it’s not a kind of error you want the calling code to have to explicitly -handle. In fact, there’s no reasonable way for calling code to recover: the -calling *programmers* need to fix the code. Contracts for a function, -especially when a violation will cause a panic, should be explained in the API -documentation for the function. - -However, having lots of error checks in all of your functions would be verbose -and annoying. Fortunately, you can use Rust’s type system (and thus the type -checking the compiler does) to do many of the checks for you. If your function -has a particular type as a parameter, you can proceed with your code’s logic -knowing that the compiler has already ensured you have a valid value. For -example, if you have a type rather than an `Option`, your program expects to -have *something* rather than *nothing*. Your code then doesn’t have to handle -two cases for the `Some` and `None` variants: it will only have one case for -definitely having a value. Code trying to pass nothing to your function won’t -even compile, so your function doesn’t have to check for that case at runtime. -Another example is using an unsigned integer type like `u32`, which ensures the -parameter is never negative. - -### Creating Custom Types for Validation +Lorsque votre code effecture des opérations sur des valeurs, votre code devrait +d'abord vérifier que ces valeurs sont valides, et faire un `panic!` si les +valeurs ne sont sont pas correctes. C'est pour essentiellements des raisons de +sécurité : tenter de travailler avec des données invalides peut exposer votre +code à des vulnérabilités. C'est la raison principale pour laquelle la +librairie standard va faire un `panic!` si vous essayez d'accéder d'accéder à +la mémoire en dehors des limites : essayer d'accéder à de la mémoire qui n'a +pas de rapport avec la structure des données actuelle est un problème de +sécurité courant. Les fonctions ont parfois des *contrats* : leur comportement +est garanti uniquement si les données d'entrée remplissent des conditions +particulières. Faire un panic quand le contrat est violé est sensé car une +violation de contrat indique toujours un bogue du coté de l'appelant, et ce +n'est le genre d'erreur que vous voulez que le code appelant gère +explicitement. En fait, il n'y a aucun moyen raisonable de récupérer le code +d'appel : le *développeur* du code appelant doit corriger le code. Les contrats +de foncion, en particulier quand une violation va faire un panic, doivent être +expliqués dans la documentation de l'API pour la fonction. + +Cependant, avoir beaucoup de vérifications d'erreurs dans toutes vos fonctions +risque d'être verbeux et ennuyeux. Heureusement, vous pouvez utiliser le +système de type de Rust (et donc la vérification de type du compilateur) pour +faire une partie des vérifcations à votre place. Si votre fonction un paramètre +d'un type particulier, vous pouvez continuer à écrire votre code en sachant que +le compilateur s'est déjà assuré que vous avez une valeur valide. Par exemple, +si vous avez un type de valeur plutôt que un `Option`, votre programme +s'attends d'avoir *autre chose* plutôt que *rien*. Votre code n'a donc pas à +gérer les deux cas de variantes `Some` et `None` : il n'aura qu'un seul cas +pour avoir une valeur. Du code qui essaye de ne rien fournir à votre fonction +ne compilera même pas, donc votre fonction n'a pas besoin de vérifier ce cas-ci +lors de l'exécution. Un autre exemple est d'utiliser un type unsigned integer +comme `u32`, qui garantit que le paramètre n'est jamais négatif. + +### Créer des types personnalisés pour la Validation Let’s take the idea of using Rust’s type system to ensure we have a valid value one step further and look at creating a custom type for validation. Recall the From 08b271aeb134aaaac79bce68324f72134bba672f Mon Sep 17 00:00:00 2001 From: Jimskapt Date: Sun, 31 Dec 2017 10:16:18 +0100 Subject: [PATCH 18/20] Finishing translating ch09-03 in french. --- .../src/ch09-03-to-panic-or-not-to-panic.md | 168 ++++++++++-------- 1 file changed, 89 insertions(+), 79 deletions(-) diff --git a/second-edition/src/ch09-03-to-panic-or-not-to-panic.md b/second-edition/src/ch09-03-to-panic-or-not-to-panic.md index 9c8e89dbb5..c2a8e128d7 100644 --- a/second-edition/src/ch09-03-to-panic-or-not-to-panic.md +++ b/second-edition/src/ch09-03-to-panic-or-not-to-panic.md @@ -136,20 +136,22 @@ comme `u32`, qui garantit que le paramètre n'est jamais négatif. ### Créer des types personnalisés pour la Validation -Let’s take the idea of using Rust’s type system to ensure we have a valid value -one step further and look at creating a custom type for validation. Recall the -guessing game in Chapter 2 where our code asked the user to guess a number -between 1 and 100. We never validated that the user’s guess was between those -numbers before checking it against our secret number; we only validated that -the guess was positive. In this case, the consequences were not very dire: our -output of “Too high” or “Too low” would still be correct. It would be a useful -enhancement to guide the user toward valid guesses and have different behavior -when a user guesses a number that’s out of range versus when a user types, for -example, letters instead. - -One way to do this would be to parse the guess as an `i32` instead of only a -`u32` to allow potentially negative numbers, and then add a check for the -number being in range, like so: +Allons plus loin dans l'idée d'utiliser le système de types de Rust pour +assurer d'avoir une valeur valide en créant un type personnalisé pour +validation. Souvenez-vous du jeu du plus ou du moins du Chapitre 2 où notre +code demandait à l'utilisateur de deviner un nombre entre 1 et 100. Nous +n'avons jamais validé que le nombre fourni par l'utilisateur était entre ces +nombres avant de le comparer à notre nombre secret; nous avons seulement validé +que le nombre était positif. Dans ce cas, les conséquences ne sont pas très +graves : notre resultat "Too high" ou "Too low" sera toujours correct. Ce +serait une amélioration utile pour guider les suppositions de l'utilisateur +vers des valeurs valides et d'avoir différents comportements quand un +utilisateur propose un nombre en dehors des limites versus quand un utilisateur +renseigne, par exemple, des lettres à la place. + +Une façon de faire cela serait de faire un parse du nombre rensigné en un `i32` +plutôt que seulement un `u32` pour permettre des potentiels nombres négatifs, +et ensuite vérifier que le nombre est dans la plage autorisée, comme ceci : ```rust,ignore loop { @@ -170,23 +172,25 @@ loop { } ``` -The `if` expression checks whether our value is out of range, tells the user -about the problem, and calls `continue` to start the next iteration of the loop -and ask for another guess. After the `if` expression, we can proceed with the -comparisons between `guess` and the secret number knowing that `guess` is -between 1 and 100. - -However, this is not an ideal solution: if it was absolutely critical that the -program only operated on values between 1 and 100, and it had many functions -with this requirement, it would be tedious (and potentially impact performance) -to have a check like this in every function. - -Instead, we can make a new type and put the validations in a function to create -an instance of the type rather than repeating the validations everywhere. That -way, it’s safe for functions to use the new type in their signatures and -confidently use the values they receive. Listing 9-9 shows one way to define a -`Guess` type that will only create an instance of `Guess` if the `new` function -receives a value between 1 and 100: +L'expression du `if` vérifie si nous valeur est en dehors des limites, et +informe l'utilisateur du problème, et utilise `continue` pour passer à la +prochaine itération de la boucle et demander un nouveau nombre à deviner. Après +l'expression `if`, nous pouvons continuer avec la comparaison entre `guess` et +le nombre secret en sachant que `guess` est entre 1 et 100. + +Cependant, ce n'est pas une solution idéale : si c'était absolument critique +que le programme travaille avec des valeurs entre 1 et 100, et qu'il aurait de +nombreuses fonctions qui exige cela, cela pourait être fastidieux (et cela +impacterait potentiellement la performance) de faire une validation comme +celle-ci dans chaque fonction. + +A la place, nous pourrions construire un nouveau type et y intégrer les +validations dans une fonction pour créer une instance de ce type plutôt que de +répliquer les validations partout. De cette manière, c'est plus sûr pour les +fonctions d'utiliser le nouveau type dans leurs signatures et d'utiliser avec +confiance les valeurs qu'ils reçoivent. L'entrée 9-9 montre une façon de +définir un type `Guess` qui ne créera une instance de `Guess` uniquement si la +fonction `new` reçoit une valeur entre 1 et 100 : ```rust pub struct Guess { @@ -210,51 +214,57 @@ impl Guess { } ``` -Listing 9-9: A `Guess` type that will only continue with -values between 1 and 100 - -First, we define a struct named `Guess` that has a field named `value` that -holds a `u32`. This is where the number will be stored. - -Then we implement an associated function named `new` on `Guess` that creates -instances of `Guess` values. The `new` function is defined to have one -parameter named `value` of type `u32` and to return a `Guess`. The code in the -body of the `new` function tests `value` to make sure it’s between 1 and 100. -If `value` doesn’t pass this test, we make a `panic!` call, which will alert -the programmer who is writing the calling code that they have a bug they need -to fix, because creating a `Guess` with a `value` outside this range would -violate the contract that `Guess::new` is relying on. The conditions in which -`Guess::new` might panic should be discussed in its public-facing API -documentation; we’ll cover documentation conventions indicating the possibility -of a `panic!` in the API documentation that you create in Chapter 14. If -`value` does pass the test, we create a new `Guess` with its `value` field set -to the `value` parameter and return the `Guess`. - -Next, we implement a method named `value` that borrows `self`, doesn’t have any -other parameters, and returns a `u32`. This is a kind of method sometimes -called a *getter*, because its purpose is to get some data from its fields and -return it. This public method is necessary because the `value` field of the -`Guess` struct is private. It’s important that the `value` field is private so -code using the `Guess` struct is not allowed to set `value` directly: code -outside the module *must* use the `Guess::new` function to create an instance -of `Guess`, which ensures there’s no way for a `Guess` to have a `value` that -hasn’t been checked by the conditions in the `Guess::new` function. - -A function that has a parameter or returns only numbers between 1 and 100 could -then declare in its signature that it takes or returns a `Guess` rather than a -`u32` and wouldn’t need to do any additional checks in its body. - -## Summary - -Rust’s error handling features are designed to help you write more robust code. -The `panic!` macro signals that your program is in a state it can’t handle and -lets you tell the process to stop instead of trying to proceed with invalid or -incorrect values. The `Result` enum uses Rust’s type system to indicate that -operations might fail in a way that your code could recover from. You can use -`Result` to tell code that calls your code that it needs to handle potential -success or failure as well. Using `panic!` and `Result` in the appropriate -situations will make your code more reliable in the face of inevitable problems. - -Now that you’ve seen useful ways that the standard library uses generics with -the `Option` and `Result` enums, we’ll talk about how generics work and how you -can use them in your code in the next chapter. +Entrée 9-9: un type `Guess` qui ne va continuer +uniquement su la valeur est entre 1 et 100 + +Premièrement, nous définissons un struct qui s'appelle `Guess` qui a un champ +`value` qui stocke un `u32`. C'est la que le nombre sera stocké. + +Ensuite, nous ajoutons un fonction associée `new` sur `Guess` qui crée des +instances de `Guess`. La fonction `new` est conçue pour avoir un paramètre +`value` de type `u32` et de retourner un `Guess`. Le code dans le corps de la +fonction `new` vérifie `value` pour s'assurer que c'est bien entre 1 et 100. +Si `value` ne échoue à ce test, nous faisons un `panic!`, qui alertera le +développeur qui écrit le code appellant qu'ils ont un bogue qu'ils ont besoin +de régler, car créer un `Guess` avec un `value` en dehors de cette plage va +violer le contrat sur lequel `Guess::new` s'appuie. Les conditions dans +lesquels `Guess::new` va faire un panic devrait être explicité dans sa +documentationsur l'API ouverte au public; nous verrons les conventions de +documentation pour indiquer un `panic!` lorsque vous créerez votre +documentation d'API au Chapitre 14. Si `value` réussit le test, nous allons +créer un nouveau `Guess` avec son champ `value` assigné au paramètre `value` +et retourner le `Guess`. + +Ensuite, nous implémentons une méthode `value` qui emprunte `self`, qui n'a +aucun autre paramètre, et retourne un `u32`. C'est un type de méthode qui est +parfois appellé un *getter*, car sa fonction est de récupérer (NdT: get) des +données des champs et de les retourner. Cette méthode publique est nécessaire +car le champ `value` du stuct `Guess` est privé. C'est important que le champ +`value` soit privé pour que le code qui utilise la struct `Guess` ne puisse pas +assigner `value` directement : le code en dehors du module *doit* utiliser la +fonction `Guess::new` pour créer une instance de `Guess`, qui s'assure qu'il +n'y a pas de façon pour un `Guess` d'avoir un `value` qui n'a pas été vérifié +par les fonctions dans la fonction `Guess:new`. + +Une fonction qui a un paramètre ou qui retourne des nombres uniquement entre 1 +et 100 peut ensuite utiliser dans sa signature qu'elle prend en paramètre ou +retourne un `Guess` plutôt qu'un `u32` et n'aura pas besoin de faire des +vérifications supplémentaires dans son code. + +## Résumé + +Les fonctionnalités de gestion d'erreurs de Rust sont conçues pour vous aider à +écrire du code plus résilient. La macro `panic!` signale que votre programme +fonctionne dans ce mauvaises conditions qu'il ne peut pas gérer et vous permet +de dire au processus de s'arrêter au lieu d'essayer de continuer avec des +valeurs invalides ou incorrectes. Le enum `Result` utilise le système de type +de Rust pour avertir que l'opération peut échouer d'une manière que votre code +pourrait corriger. Vous pouvez utiliser `Result` pour dire au code qui appelle +votre code qu'il a besoin de gérer le résultat et aussi les potentielles +erreurs. Utiliser `panic!` et `Result` de manière appropriée va faire de votre +code plus fiable face à des problèmes inévitables. + +Maintenant que vous avez vu les pratiques utiles que la librairie standard +utilise avec les enum `Option` et `Result`, nous allons voir au chapitre +suivant comment les génériques fonctionnent et comment vous pouvez les utiliser +dans votre code. From 58e4b3be674f9f7a76f019ebc4ba41509f601223 Mon Sep 17 00:00:00 2001 From: Jimskapt Date: Sun, 31 Dec 2017 10:53:42 +0100 Subject: [PATCH 19/20] Typo fixing on ch09-03. --- .../src/ch09-03-to-panic-or-not-to-panic.md | 146 +++++++++--------- 1 file changed, 73 insertions(+), 73 deletions(-) diff --git a/second-edition/src/ch09-03-to-panic-or-not-to-panic.md b/second-edition/src/ch09-03-to-panic-or-not-to-panic.md index c2a8e128d7..fcfea710cc 100644 --- a/second-edition/src/ch09-03-to-panic-or-not-to-panic.md +++ b/second-edition/src/ch09-03-to-panic-or-not-to-panic.md @@ -2,7 +2,7 @@ Donc, comment décider quand on doit faire un `panic!` et quand nous devons retourner un `Result` ? Quand un code fait un panic, il n'y a pas de moyen de -continuer l'exécution. Vous pouriez faire appel à `panic!` pour n'importe +continuer l'exécution. Vous pourriez faire appel à `panic!` pour n'importe quelle situation d'erreur, peux importe s'il est possible de continuer l'exécution ou non, mais alors vous prenez la décision de tout arrêter à la place du code appelant. Quand vous choisissez de retourner une valeur `Result`, @@ -11,25 +11,25 @@ décisions à sa place. Le code appelant peut choisir d'essayer de récupérer l'erreur de manière appropriée à cette situation, ou il peut décider que dans ce cas une valeur `Err` est irrécupérable, donc utiliser `panic!` et changer votre erreur récupérable en erreur irrécupérable. Ainsi, retourner `Result` est -un bon choix par défaut quand vous construisez une fonction qui peux échouer. +un bon choix par défaut quand vous construisez une fonction qui peut échouer. Dans quelques situations, c'est plus approprié d'écrire du code qui fait un panic au lieu de retourner un `Result`, mais elles sont moins fréquentes. -Voyons pourquoi ils est approprié pourquoi il est plus approprié de faire un -panic dans des examples, des prototypes, et des tests; ensuite des situations -où vous savez qu'en tant qu'humain qu'une méthode ne peux pas échouer mais que -le compilateur n'a pas de raison de le faire; et nous alons conclure par +Voyons pourquoi il est approprié pourquoi il est plus approprié de faire un +panic dans des exemples, des prototypes, et des tests; ensuite des situations +où vous savez qu'en tant qu'humain qu'une méthode ne peut pas échouer, mais que +le compilateur n'a pas de raison de le faire; et nous allons conclure par quelques lignes conductrices générales sur comment décider s'il faut paniquer dans le code des librairies. -### Les examples, prototypes, et les tests sont les endroit parfaits pour Panic +### Les exemples, prototypes, et les tests sont les endroits parfaits pour Panic -Quand vous écrivez un example pour illustrer un concept, avoir un code de -gestion des erreurs très résiliente peut rendre l'exemple moins claire. Dans -les examples, il est courrant d'utiliser une méthode comme `unwrap` qui peut -faire un `panic!` qui remplace le code de gestion de l'erreur que vous -utiliseriez dans votre application, qui peux changer en fonction de ce que le -reste de votre code va faire. +Quand vous écrivez un exemple pour illustrer un concept, avoir un code de +gestion des erreurs très résilient peut rendre l'exemple moins clair. Dans les +exemples, il est courant d'utiliser une méthode comme `unwrap` qui peut faire +un `panic!` qui remplace le code de gestion de l'erreur que vous utiliseriez +dans votre application, qui peut changer en fonction de ce que le reste de +votre code va faire. De la même manière, les méthodes `unwrap` et `expect` sont très pratiques pour coder des prototypes, avant de décider comment gérer les erreurs. Ce sont des @@ -38,20 +38,20 @@ rendre votre code plus résilient aux échecs. Si l'appel à une méthode échoue dans un test, nous voulons que tout le test échoue, même si cette méthode n'est pas la fonctionnalité que nous testons. -Parceque `panic!` est la manière de le marquer un échec, utiliser `unwrap` ou +Parce que `panic!` est la manière de le marquer un échec, utiliser `unwrap` ou `expect` est exactement ce qui est nécessaire. ### Les cas où vous avez plus d'informations que le compilateur Il peut parfois être approprié d'utiliser `unwrap` quand vous avez un code -logique qui garanti que `Result` aura toujours une valeur de type `Ok`, mais -que c'est une logique que le compilateur ne comprends pas. Vous travaillez -toujours une valeur de type `Result` que vous devez gérer : quelque soit +logique qui garantie que `Result` aura toujours une valeur de type `Ok`, mais +que c'est une logique que le compilateur ne comprend pas. Vous travaillez +toujours une valeur de type `Result` que vous devez gérer : quel que soit l'instruction que vous appelez, elle a toujours la possibilité d'échouer, même si dans ce cas particulier, c'est logiquement impossible. Si vous êtes sûr en inspectant le code manuellement que vous n'allez jamais obtenir une variante de `Err`, il est tout à fait acceptable d'utiliser `unwrap`. Voici un -example : +exemple : ```rust use std::net::IpAddr; @@ -69,42 +69,42 @@ compilateur n'est pas encore suffisamment intelligent pour analyser que cette chaine de caractères est toujours une adresse IP valide. Si le texte de l'adresse IP provient de l'utilisateur plutôt que d'être codé en dur dans le programme, et fait en sorte qu'il y a désormais une possibilité d'erreur, nous -devrions gérer le `Result` de manière plus résiliente désormais. +devrions désormais gérer le `Result` de manière plus résiliente. ### Recommandations pour gérer les erreurs Il est recommandé de faire un `panic!` dans votre code lorsqu'il s'exécute dans de mauvaises conditions. Dans ce sens, les mauvaises conditions sont lorsque un -postulat, une garantie, un contrat ou une invariance a été rompue, comme des -valeurs invalides, contradictoires ou manquantes fournies à votre code, par un +postulat, une garantie, un contrat ou une invariante a été rompue, comme des +valeurs invalides, contradictoires ou manquantes fournis à votre code, par un ou plusieurs des éléments suivants : * Ces mauvaises conditions ne sont pas *prévues* pour surgir de temps en temps. * Après cette instruction, votre code a besoin de ne pas être dans ces mauvaises conditions. -* Il n'y pas de bonne façon de coder ces informations dans les types que vous +* Il n'y a pas de bonne façon de coder ces informations dans les types que vous utilisez. Si quelqu'un utilise votre code et lui fournit des valeurs qui n'ont pas de sens, la meilleure des choses à faire et de faire un `panic!` et avertir -le développeur de votre librairie du bogue dans leur code afin qu'il le règle +le développeur de votre librairie du bogue dans leur code afin qu'il le résoud pendant la phase de développement. De la même manière, `panic!` est parfois -approprié si vous appellez un code externe dont vous n'avez pas la main dessus, +approprié si vous appelez un code externe dont vous n'avez pas la main dessus, et qu'il retourne de mauvaises conditions que vous ne pouvez pas corriger. -Lorsque les condtions sont mauvaises, mais qui est prévu que cela arrive peu -importe la façon que vous écrivez votre code, il est plus aproprié de retourner -un `Result` plutôt que faire appel à `panic!`. Il peut s'agir par exemple d'un -un parseur qui reçoit des données éronnées, ou une requête HTTP qui renvoit un -statut qui indique que vous avez atteint une limite de débit. Dans ce cas, vous -devriez que cet échec est un possibilité en retournant un `Result` pour -propager ces mauvaises conditions vers le haut pour que le code appelant puisse -décider quoi faire pour gérer le problème. Faire un `panic!` ne serait pas la -manière la approprié ici pour gérer ces problèmes. - -Lorsque votre code effecture des opérations sur des valeurs, votre code devrait +Lorsque les conditions sont mauvaises, mais qui est prévu que cela arrive peu +importe la façon dont vous écrivez votre code, il est plus approprié de +retourner un `Result` plutôt que faire appel à `panic!`. Il peut s'agir par +exemple d'un parseur qui reçoit des données erronées, ou une requête HTTP +qui renvoie un statut qui indique que vous avez atteint une limite de débit. +Dans ce cas, vous devriez que cet échec est une possibilité en retournant un +`Result` pour propager ces mauvaises conditions vers le haut pour que le code +appelant puisse décider quoi faire pour gérer le problème. Faire un `panic!` ne +serait pas la manière la plus appropriée ici pour gérer ces problèmes. + +Lorsque votre code effectue des opérations sur des valeurs, votre code devrait d'abord vérifier que ces valeurs sont valides, et faire un `panic!` si les -valeurs ne sont sont pas correctes. C'est pour essentiellements des raisons de +valeurs ne sont sont pas correctes. C'est pour essentiellement des raisons de sécurité : tenter de travailler avec des données invalides peut exposer votre code à des vulnérabilités. C'est la raison principale pour laquelle la librairie standard va faire un `panic!` si vous essayez d'accéder d'accéder à @@ -112,27 +112,27 @@ la mémoire en dehors des limites : essayer d'accéder à de la mémoire qui n'a pas de rapport avec la structure des données actuelle est un problème de sécurité courant. Les fonctions ont parfois des *contrats* : leur comportement est garanti uniquement si les données d'entrée remplissent des conditions -particulières. Faire un panic quand le contrat est violé est sensé car une -violation de contrat indique toujours un bogue du coté de l'appelant, et ce +particulières. Faire un panic quand le contrat est violé est sensé, car une +violation de contrat indique toujours un bogue du côté de l'appelant, et ce n'est le genre d'erreur que vous voulez que le code appelant gère -explicitement. En fait, il n'y a aucun moyen raisonable de récupérer le code +explicitement. En fait, il n'y a aucun moyen raisonnable de récupérer le code d'appel : le *développeur* du code appelant doit corriger le code. Les contrats -de foncion, en particulier quand une violation va faire un panic, doivent être +de fonction, en particulier quand une violation va faire un panic, doivent être expliqués dans la documentation de l'API pour la fonction. Cependant, avoir beaucoup de vérifications d'erreurs dans toutes vos fonctions risque d'être verbeux et ennuyeux. Heureusement, vous pouvez utiliser le système de type de Rust (et donc la vérification de type du compilateur) pour -faire une partie des vérifcations à votre place. Si votre fonction un paramètre -d'un type particulier, vous pouvez continuer à écrire votre code en sachant que -le compilateur s'est déjà assuré que vous avez une valeur valide. Par exemple, -si vous avez un type de valeur plutôt que un `Option`, votre programme -s'attends d'avoir *autre chose* plutôt que *rien*. Votre code n'a donc pas à -gérer les deux cas de variantes `Some` et `None` : il n'aura qu'un seul cas -pour avoir une valeur. Du code qui essaye de ne rien fournir à votre fonction -ne compilera même pas, donc votre fonction n'a pas besoin de vérifier ce cas-ci -lors de l'exécution. Un autre exemple est d'utiliser un type unsigned integer -comme `u32`, qui garantit que le paramètre n'est jamais négatif. +faire une partie des vérifications à votre place. Si votre fonction un +paramètre d'un type particulier, vous pouvez continuer à écrire votre code en +sachant que le compilateur s'est déjà assuré que vous avez une valeur valide. +Par exemple, si vous avez un type de valeur plutôt qu'un `Option`, votre +programme s'attend d'avoir *autre chose* plutôt que *rien*. Votre code n'a +donc pas à gérer les deux cas de variantes `Some` et `None` : il n'aura qu'un +seul cas pour avoir une valeur. Du code qui essaye de ne rien fournir à votre +fonction ne compilera même pas, donc votre fonction n'a pas besoin de vérifier +ce cas-ci lors de l'exécution. Un autre exemple est d'utiliser un type unsigned +integer comme `u32`, qui garantit que le paramètre n'est jamais négatif. ### Créer des types personnalisés pour la Validation @@ -143,15 +143,16 @@ code demandait à l'utilisateur de deviner un nombre entre 1 et 100. Nous n'avons jamais validé que le nombre fourni par l'utilisateur était entre ces nombres avant de le comparer à notre nombre secret; nous avons seulement validé que le nombre était positif. Dans ce cas, les conséquences ne sont pas très -graves : notre resultat "Too high" ou "Too low" sera toujours correct. Ce +graves : notre résultat "Too high" ou "Too low" sera toujours correct. Ce serait une amélioration utile pour guider les suppositions de l'utilisateur vers des valeurs valides et d'avoir différents comportements quand un utilisateur propose un nombre en dehors des limites versus quand un utilisateur renseigne, par exemple, des lettres à la place. -Une façon de faire cela serait de faire un parse du nombre rensigné en un `i32` -plutôt que seulement un `u32` pour permettre des potentiels nombres négatifs, -et ensuite vérifier que le nombre est dans la plage autorisée, comme ceci : +Une façon de faire cela serait de faire un parse du nombre renseigné en un +`i32` plutôt que seulement un `u32` pour permettre des potentiels nombres +négatifs, et ensuite vérifier que le nombre est dans la plage autorisée, comme +ceci : ```rust,ignore loop { @@ -180,7 +181,7 @@ le nombre secret en sachant que `guess` est entre 1 et 100. Cependant, ce n'est pas une solution idéale : si c'était absolument critique que le programme travaille avec des valeurs entre 1 et 100, et qu'il aurait de -nombreuses fonctions qui exige cela, cela pourait être fastidieux (et cela +nombreuses fonctions qui exige cela, cela pourrait être fastidieux (et cela impacterait potentiellement la performance) de faire une validation comme celle-ci dans chaque fonction. @@ -215,31 +216,30 @@ impl Guess { ``` Entrée 9-9: un type `Guess` qui ne va continuer -uniquement su la valeur est entre 1 et 100 +uniquement si la valeur est entre 1 et 100 Premièrement, nous définissons un struct qui s'appelle `Guess` qui a un champ -`value` qui stocke un `u32`. C'est la que le nombre sera stocké. +`value` qui stocke un `u32`. C'est là que le nombre sera stocké. -Ensuite, nous ajoutons un fonction associée `new` sur `Guess` qui crée des +Ensuite, nous ajoutons une fonction associée `new` sur `Guess` qui crée des instances de `Guess`. La fonction `new` est conçue pour avoir un paramètre `value` de type `u32` et de retourner un `Guess`. Le code dans le corps de la fonction `new` vérifie `value` pour s'assurer que c'est bien entre 1 et 100. -Si `value` ne échoue à ce test, nous faisons un `panic!`, qui alertera le -développeur qui écrit le code appellant qu'ils ont un bogue qu'ils ont besoin -de régler, car créer un `Guess` avec un `value` en dehors de cette plage va -violer le contrat sur lequel `Guess::new` s'appuie. Les conditions dans -lesquels `Guess::new` va faire un panic devrait être explicité dans sa -documentationsur l'API ouverte au public; nous verrons les conventions de -documentation pour indiquer un `panic!` lorsque vous créerez votre -documentation d'API au Chapitre 14. Si `value` réussit le test, nous allons -créer un nouveau `Guess` avec son champ `value` assigné au paramètre `value` -et retourner le `Guess`. +Si `value` échoue à ce test, nous faisons un `panic!`, qui alertera le +développeur qui écrit le code appelant qu'il a un bogue qu'il a besoin de +régler, car créer un `Guess` avec un `value` en dehors de cette plage va violer +le contrat sur lequel `Guess::new` s'appuie. Les conditions dans lesquels +`Guess::new` va faire un panic devrait être explicité dans sa documentation sur +l'API ouverte au public; nous verrons les conventions de documentation pour +indiquer un `panic!` lorsque vous créerez votre documentation d'API au +Chapitre 14. Si `value` réussit le test, nous allons créer un nouveau `Guess` +avec son champ `value` assigné au paramètre `value` et retourner le `Guess`. Ensuite, nous implémentons une méthode `value` qui emprunte `self`, qui n'a aucun autre paramètre, et retourne un `u32`. C'est un type de méthode qui est -parfois appellé un *getter*, car sa fonction est de récupérer (NdT: get) des -données des champs et de les retourner. Cette méthode publique est nécessaire -car le champ `value` du stuct `Guess` est privé. C'est important que le champ +parfois appelé un *getter*, car sa fonction est de récupérer (NdT: get) des +données des champs et de les retourner. Cette méthode publique est nécessaire, +car le champ `value` du struct `Guess` est privé. C'est important que le champ `value` soit privé pour que le code qui utilise la struct `Guess` ne puisse pas assigner `value` directement : le code en dehors du module *doit* utiliser la fonction `Guess::new` pour créer une instance de `Guess`, qui s'assure qu'il @@ -255,7 +255,7 @@ vérifications supplémentaires dans son code. Les fonctionnalités de gestion d'erreurs de Rust sont conçues pour vous aider à écrire du code plus résilient. La macro `panic!` signale que votre programme -fonctionne dans ce mauvaises conditions qu'il ne peut pas gérer et vous permet +fonctionne dans de mauvaises conditions qu'il ne peut pas gérer et vous permet de dire au processus de s'arrêter au lieu d'essayer de continuer avec des valeurs invalides ou incorrectes. Le enum `Result` utilise le système de type de Rust pour avertir que l'opération peut échouer d'une manière que votre code @@ -265,6 +265,6 @@ erreurs. Utiliser `panic!` et `Result` de manière appropriée va faire de votre code plus fiable face à des problèmes inévitables. Maintenant que vous avez vu les pratiques utiles que la librairie standard -utilise avec les enum `Option` et `Result`, nous allons voir au chapitre +utilise avec les enums `Option` et `Result`, nous allons voir au chapitre suivant comment les génériques fonctionnent et comment vous pouvez les utiliser dans votre code. From 2cd61c4acd038708b40f052248d5b2ca2602b57a Mon Sep 17 00:00:00 2001 From: Jimskapt Date: Sun, 31 Dec 2017 19:45:56 +0100 Subject: [PATCH 20/20] Forgot to translate a sentence in ch09-02. Not sure about its accuracy. --- .../ch09-02-recoverable-errors-with-result.md | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/second-edition/src/ch09-02-recoverable-errors-with-result.md b/second-edition/src/ch09-02-recoverable-errors-with-result.md index 549cf579f6..51c0fd600d 100644 --- a/second-edition/src/ch09-02-recoverable-errors-with-result.md +++ b/second-edition/src/ch09-02-recoverable-errors-with-result.md @@ -200,15 +200,16 @@ essayons d'ouvrir n'existe pas encore. La condition `if error.kind() == ErrorKind::NotFound` est ce qu'on appelle un *match guard* : c'est une condition supplémentaire sur une branche d'un bloc -`match` qui raffine le pattern d'une branche. Cette condition doit être valide -pour que le code de cette branche soit exécutée; autrement, le pattern matching -s'orientera sur la branche suivante dans le `match`. ** (TODO) The `ref` in the -pattern is needed so `error` is not moved into the guard condition but is -merely referenced by it.** La raison pour laquelle `ref` est utilisé pour -stocker une référence dans le pattern plutôt que un `&` va être expliquée en -détails dans le Chapitre 18. Pour faire court, dans le cas d'un pattern, `&` -est associé à une référence et nous retourne sa valeur, mais `ref` associe une -valeur et nous donne une référence vers elle. +`match` qui raffine le pattern d'une branche. Cette condition doit être vraie +pour que le code de cette branche soit exécuté; autrement, le pattern matching +s'orientera sur la branche suivante dans le `match`. Le `ref` dans le pattern +est requis pour que `error` ne soit pas déplacée dans dans le conditon du match +guard mais qu'elle soit simplement référencée par elle (NdT: vérifier la trad). +La raison pour laquelle `ref` est utilisé pour stocker une référence dans le +pattern plutôt que un `&` va être expliquée en détails dans le Chapitre 18. +Pour faire court, dans le cas d'un pattern, `&` est associé à une référence et +nous retourne sa valeur, mais `ref` associe une valeur et nous donne une +référence vers elle. Le cas que nous voulons vérifier dans le match guard est lorsque la valeur retournée par `error.kind()` est la variante de `NotFound` de l'enum