From 1cc979b771cab2d9e190bbaef6aaf05e816b3c68 Mon Sep 17 00:00:00 2001 From: Yuning Zhang Date: Wed, 2 Jan 2019 12:01:48 -0500 Subject: [PATCH 001/117] Update error messages --- src/ch02-00-guessing-game-tutorial.md | 2 +- src/ch03-05-control-flow.md | 4 ++-- src/ch10-01-syntax.md | 4 ++-- src/ch13-01-closures.md | 2 +- 4 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/ch02-00-guessing-game-tutorial.md b/src/ch02-00-guessing-game-tutorial.md index 897d0c8d05..70bc88816d 100644 --- a/src/ch02-00-guessing-game-tutorial.md +++ b/src/ch02-00-guessing-game-tutorial.md @@ -668,7 +668,7 @@ error[E0308]: mismatched types --> src/main.rs:23:21 | 23 | match guess.cmp(&secret_number) { - | ^^^^^^^^^^^^^^ expected struct `std::string::String`, found integral variable + | ^^^^^^^^^^^^^^ expected struct `std::string::String`, found integer | = note: expected type `&std::string::String` = note: found type `&{integer}` diff --git a/src/ch03-05-control-flow.md b/src/ch03-05-control-flow.md index 6c7c2c0211..b78ba10003 100644 --- a/src/ch03-05-control-flow.md +++ b/src/ch03-05-control-flow.md @@ -95,7 +95,7 @@ error[E0308]: mismatched types --> src/main.rs:4:8 | 4 | if number { - | ^^^^^^ expected bool, found integral variable + | ^^^^^^ expected bool, found integer | = note: expected type `bool` found type `{integer}` @@ -239,7 +239,7 @@ error[E0308]: if and else have incompatible types 6 | | } else { 7 | | "six" 8 | | }; - | |_____^ expected integral variable, found &str + | |_____^ expected integer, found &str | = note: expected type `{integer}` found type `&str` diff --git a/src/ch10-01-syntax.md b/src/ch10-01-syntax.md index 9595162e55..2239901425 100644 --- a/src/ch10-01-syntax.md +++ b/src/ch10-01-syntax.md @@ -207,8 +207,8 @@ error[E0308]: mismatched types --> src/main.rs:7:38 | 7 | let wont_work = Point { x: 5, y: 4.0 }; - | ^^^ expected integral variable, found -floating-point variable + | ^^^ expected integer, found +floating-point number | = note: expected type `{integer}` found type `{float}` diff --git a/src/ch13-01-closures.md b/src/ch13-01-closures.md index 05c97c7e6f..f679c1431e 100644 --- a/src/ch13-01-closures.md +++ b/src/ch13-01-closures.md @@ -402,7 +402,7 @@ error[E0308]: mismatched types | | let n = example_closure(5); | ^ expected struct `std::string::String`, found - integral variable + integer | = note: expected type `std::string::String` found type `{integer}` From 28240159c21e9d0912feee863fb197508800a744 Mon Sep 17 00:00:00 2001 From: Steve Klabnik Date: Mon, 7 Jan 2019 13:44:25 -0500 Subject: [PATCH 002/117] tweak opening paragraph of deref coercions Fixes #1408 --- src/ch15-02-deref.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ch15-02-deref.md b/src/ch15-02-deref.md index 65bbbad6fb..8e54844173 100644 --- a/src/ch15-02-deref.md +++ b/src/ch15-02-deref.md @@ -10,7 +10,7 @@ Let’s first look at how the dereference operator works with regular references Then we’ll try to define a custom type that behaves like `Box`, and see why the dereference operator doesn’t work like a reference on our newly defined type. We’ll explore how implementing the `Deref` trait makes it possible for -smart pointers to work in a similar way as references. Then we’ll look at +smart pointers to work in way similar to references. Then we’ll look at Rust’s *deref coercion* feature and how it lets us work with either references or smart pointers. From ac4b9cd9d8fe12333c33ac646694250464af516f Mon Sep 17 00:00:00 2001 From: Komron Date: Thu, 18 Apr 2019 17:30:21 +0200 Subject: [PATCH 003/117] Ferris does-not-compile added (ch9.2) --- src/ch09-02-recoverable-errors-with-result.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/ch09-02-recoverable-errors-with-result.md b/src/ch09-02-recoverable-errors-with-result.md index 80d07b3276..b1a335c7cc 100644 --- a/src/ch09-02-recoverable-errors-with-result.md +++ b/src/ch09-02-recoverable-errors-with-result.md @@ -51,7 +51,7 @@ 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: -```rust,ignore +```rust,ignore,does_not_compile let f: u32 = File::open("hello.txt"); ``` @@ -481,7 +481,7 @@ must be a `Result` to be compatible with this `return`. Let’s look at what happens if we use the `?` operator in the `main` function, which you’ll recall has a return type of `()`: -```rust,ignore +```rust,ignore,does_not_compile use std::fs::File; fn main() { From 05bd3e0b7f6bed0b9c053e570b028c7db186199a Mon Sep 17 00:00:00 2001 From: Nan Xiao Date: Thu, 25 Apr 2019 10:43:38 +0800 Subject: [PATCH 004/117] A small typo? --- src/ch03-01-variables-and-mutability.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ch03-01-variables-and-mutability.md b/src/ch03-01-variables-and-mutability.md index 6f5e6c7b15..b14bba5244 100644 --- a/src/ch03-01-variables-and-mutability.md +++ b/src/ch03-01-variables-and-mutability.md @@ -65,7 +65,7 @@ But mutability can be very useful. Variables are immutable only by default; as you did in Chapter 2, you can make them mutable by adding `mut` in front of the variable name. In addition to allowing this value to change, `mut` conveys intent to future readers of the code by indicating that other parts of the code -will be changing this variable value. +will be changing this variable's value. For example, let’s change *src/main.rs* to the following: From 0e47382af63e6c85835c16df44e8f6179e39449d Mon Sep 17 00:00:00 2001 From: Alex Tokarev Date: Sat, 20 Apr 2019 19:24:56 +0300 Subject: [PATCH 005/117] Make the code not compile to match the text MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit > First, in Listing 16-6, we’ll create a channel but not do anything with it. Note that this won’t compile yet because Rust can’t tell what type of values we want to send over the channel. That was not true, however, since the code compiled due to hidden line. This change makes the code not compile by removing it. --- src/ch16-02-message-passing.md | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/ch16-02-message-passing.md b/src/ch16-02-message-passing.md index 7cb4cfa8d3..56181eaf79 100644 --- a/src/ch16-02-message-passing.md +++ b/src/ch16-02-message-passing.md @@ -35,12 +35,11 @@ want to send over the channel. Filename: src/main.rs -```rust +```rust,ignore,does_not_compile use std::sync::mpsc; fn main() { let (tx, rx) = mpsc::channel(); -# tx.send(()).unwrap(); } ``` From 7de4a68bfe7becff15fd8399d785f3ff10fc8bfe Mon Sep 17 00:00:00 2001 From: sd234678 Date: Fri, 3 May 2019 11:05:27 +0100 Subject: [PATCH 006/117] Remove unused import in lfp --- tools/src/bin/lfp.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/src/bin/lfp.rs b/tools/src/bin/lfp.rs index e597d4515b..32b2ab2975 100644 --- a/tools/src/bin/lfp.rs +++ b/tools/src/bin/lfp.rs @@ -7,7 +7,7 @@ extern crate walkdir; use docopt::Docopt; use std::{path, fs, io}; -use std::io::{BufRead, Write}; +use std::io::BufRead; fn main () { let args: Args = Docopt::new(USAGE) From c19fca6083bad4c5b43507daa58a7d41f3ed4fdc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C3=ABl=20L=C3=A9vesque-Dion?= Date: Thu, 9 May 2019 07:20:11 -0400 Subject: [PATCH 007/117] Add missing "of" before `"duck typing"`. This seems like a typo to me : ...similar to the concept duck typing in dynamically... ...similar to the concept *of* duck typing in dynamically... --- src/ch17-02-trait-objects.md | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/src/ch17-02-trait-objects.md b/src/ch17-02-trait-objects.md index b9342ac231..0e5f1be22e 100644 --- a/src/ch17-02-trait-objects.md +++ b/src/ch17-02-trait-objects.md @@ -275,14 +275,15 @@ new type and draw it because `SelectBox` implements the `Draw` trait, which means it implements the `draw` method. This concept—of being concerned only with the messages a value responds to -rather than the value’s concrete type—is similar to the concept *duck typing* -in dynamically typed languages: if it walks like a duck and quacks like a duck, -then it must be a duck! In the implementation of `run` on `Screen` in Listing -17-5, `run` doesn’t need to know what the concrete type of each component is. -It doesn’t check whether a component is an instance of a `Button` or a -`SelectBox`, it just calls the `draw` method on the component. By specifying -`Box` as the type of the values in the `components` vector, we’ve -defined `Screen` to need values that we can call the `draw` method on. +rather than the value’s concrete type—is similar to the concept of *duck +typing* in dynamically typed languages: if it walks like a duck and quacks +like a duck, then it must be a duck! In the implementation of `run` on `Screen` +in Listing 17-5, `run` doesn’t need to know what the concrete type of each +component is. It doesn’t check whether a component is an instance of a `Button` +or a `SelectBox`, it just calls the `draw` method on the component. By +specifying `Box` as the type of the values in the `components` +vector, we’ve defined `Screen` to need values that we can call the `draw` +method on. The advantage of using trait objects and Rust’s type system to write code similar to code using duck typing is that we never have to check whether a From 48b057106646758f6453f42b7887f34b8c24caf6 Mon Sep 17 00:00:00 2001 From: Ayush Mishra Date: Mon, 13 May 2019 17:17:58 +0530 Subject: [PATCH 008/117] No need for an iterator here to fetch values The compiler will call `into_iter()` on the values. --- src/ch10-00-generics.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ch10-00-generics.md b/src/ch10-00-generics.md index a928b81e7c..b411210be2 100644 --- a/src/ch10-00-generics.md +++ b/src/ch10-00-generics.md @@ -125,7 +125,7 @@ number in two different lists. fn largest(list: &[i32]) -> i32 { let mut largest = list[0]; - for &item in list.iter() { + for &item in list { if item > largest { largest = item; } From 9f71ed226f64acc4635b617d56ede2305155fb5a Mon Sep 17 00:00:00 2001 From: Igor Tonkopryadchenko Date: Fri, 17 May 2019 08:11:39 +0300 Subject: [PATCH 009/117] Add more words to the quote from the actual Go documentation, it actually has an opposite meaning --- src/ch16-03-shared-state.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ch16-03-shared-state.md b/src/ch16-03-shared-state.md index e5491d147c..7050d4db15 100644 --- a/src/ch16-03-shared-state.md +++ b/src/ch16-03-shared-state.md @@ -2,7 +2,7 @@ Message passing is a fine way of handling concurrency, but it’s not the only one. Consider this part of the slogan from the Go language documentation again: -“communicate by sharing memory.” +“do not communicate by sharing memory.” What would communicating by sharing memory look like? In addition, why would message-passing enthusiasts not use it and do the opposite instead? From ee81907fdfb760767b7583425c31c9851bcfe7af Mon Sep 17 00:00:00 2001 From: Maxime Guerreiro Date: Mon, 20 May 2019 15:26:15 +0100 Subject: [PATCH 010/117] Mark the dangle function as does_not_compile Fixes #1964 --- src/ch04-02-references-and-borrowing.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ch04-02-references-and-borrowing.md b/src/ch04-02-references-and-borrowing.md index b44aad3e50..69e829cf04 100644 --- a/src/ch04-02-references-and-borrowing.md +++ b/src/ch04-02-references-and-borrowing.md @@ -314,7 +314,7 @@ Let’s take a closer look at exactly what’s happening at each stage of our Filename: src/main.rs -```rust,ignore +```rust,ignore,does_not_compile fn dangle() -> &String { // dangle returns a reference to a String let s = String::from("hello"); // s is a new String From db1f65fe696b3a29527fef2bad13a9d9f7cb4320 Mon Sep 17 00:00:00 2001 From: Qingping Hou Date: Sun, 26 May 2019 16:10:31 -0700 Subject: [PATCH 011/117] correct wording for integration test doc To keep the wording consistent with the first paragraph. It's a little bit confusing to use the word test here since it can be mistaken as a test function. --- src/ch11-03-test-organization.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ch11-03-test-organization.md b/src/ch11-03-test-organization.md index 56bbccbae4..5cffcccf24 100644 --- a/src/ch11-03-test-organization.md +++ b/src/ch11-03-test-organization.md @@ -132,7 +132,7 @@ fn it_adds_two() { `adder` crate We’ve added `use adder` at the top of the code, which we didn’t need in the -unit tests. The reason is that each test in the `tests` directory is a separate +unit tests. The reason is that each file in the `tests` directory is a separate crate, so we need to bring our library into each test crate’s scope. We don’t need to annotate any code in *tests/integration_test.rs* with From 158c5eb79750d497fe92298a8bee8351c7f3606a Mon Sep 17 00:00:00 2001 From: Kevin Mehall Date: Mon, 3 Jun 2019 22:19:40 -0700 Subject: [PATCH 012/117] Replace deprecated `...` range syntax with `..=` https://github.com/rust-lang/rust/issues/28237 - this is now a warning on Nightly. Fixes #1757 --- src/ch18-03-pattern-syntax.md | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/src/ch18-03-pattern-syntax.md b/src/ch18-03-pattern-syntax.md index ccdeb6608b..63eab2f7b2 100644 --- a/src/ch18-03-pattern-syntax.md +++ b/src/ch18-03-pattern-syntax.md @@ -105,9 +105,9 @@ match x { This code prints `one or two`. -### Matching Ranges of Values with `...` +### Matching Ranges of Values with `..=` -The `...` syntax allows us to match to an inclusive range of values. In the +The `..=` syntax allows us to match to an inclusive range of values. In the following code, when a pattern matches any of the values within the range, that arm will execute: @@ -115,14 +115,14 @@ arm will execute: let x = 5; match x { - 1...5 => println!("one through five"), + 1..=5 => println!("one through five"), _ => println!("something else"), } ``` If `x` is 1, 2, 3, 4, or 5, the first arm will match. This syntax is more convenient than using the `|` operator to express the same idea; instead of -`1...5`, we would have to specify `1 | 2 | 3 | 4 | 5` if we used `|`. +`1..=5`, we would have to specify `1 | 2 | 3 | 4 | 5` if we used `|`. Specifying a range is much shorter, especially if we want to match, say, any number between 1 and 1,000! @@ -136,8 +136,8 @@ Here is an example using ranges of `char` values: let x = 'c'; match x { - 'a'...'j' => println!("early ASCII letter"), - 'k'...'z' => println!("late ASCII letter"), + 'a'..='j' => println!("early ASCII letter"), + 'k'..='z' => println!("late ASCII letter"), _ => println!("something else"), } ``` @@ -783,7 +783,7 @@ were applied only to the final value in the list of values specified using the The *at* operator (`@`) lets us create a variable that holds a value at the same time we’re testing that value to see whether it matches a pattern. Listing 18-29 shows an example where we want to test that a `Message::Hello` `id` field -is within the range `3...7`. But we also want to bind the value to the variable +is within the range `3..=7`. But we also want to bind the value to the variable `id_variable` so we can use it in the code associated with the arm. We could name this variable `id`, the same as the field, but for this example we’ll use a different name. @@ -796,10 +796,10 @@ enum Message { let msg = Message::Hello { id: 5 }; match msg { - Message::Hello { id: id_variable @ 3...7 } => { + Message::Hello { id: id_variable @ 3..=7 } => { println!("Found an id in range: {}", id_variable) }, - Message::Hello { id: 10...12 } => { + Message::Hello { id: 10..=12 } => { println!("Found an id in another range") }, Message::Hello { id } => { @@ -812,7 +812,7 @@ match msg { while also testing it This example will print `Found an id in range: 5`. By specifying `id_variable -@` before the range `3...7`, we’re capturing whatever value matched the range +@` before the range `3..=7`, we’re capturing whatever value matched the range while also testing that the value matched the range pattern. In the second arm, where we only have a range specified in the pattern, the code From 4b7f70a2657bf7fb6302a146f97e5a17cfdb30e2 Mon Sep 17 00:00:00 2001 From: L0uisc Date: Thu, 6 Jun 2019 14:46:52 +0200 Subject: [PATCH 013/117] make wording clearer --- src/ch10-02-traits.md | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/ch10-02-traits.md b/src/ch10-02-traits.md index 131f6c1928..9c6e91bf46 100644 --- a/src/ch10-02-traits.md +++ b/src/ch10-02-traits.md @@ -610,12 +610,12 @@ reduce duplication but also specify to the compiler that we want the generic type to have particular behavior. The compiler can then use the trait bound information to check that all the concrete types used with our code provide the correct behavior. In dynamically typed languages, we would get an error at -runtime if we called a method on a type that the type didn’t implement. But -Rust moves these errors to compile time so we’re forced to fix the problems -before our code is even able to run. Additionally, we don’t have to write code -that checks for behavior at runtime because we’ve already checked at compile -time. Doing so improves performance without having to give up the flexibility -of generics. +runtime if we called a method on a type which didn’t implement the type which +defines the method. But Rust moves these errors to compile time so we’re forced +to fix the problems before our code is even able to run. Additionally, we don’t +have to write code that checks for behavior at runtime because we’ve already +checked at compile time. Doing so improves performance without having to give +up the flexibility of generics. Another kind of generic that we’ve already been using is called *lifetimes*. Rather than ensuring that a type has the behavior we want, lifetimes ensure From e81710c276b3839e8ec54d5f12aec4f9de88924b Mon Sep 17 00:00:00 2001 From: Robbert Date: Fri, 14 Jun 2019 14:50:32 +0200 Subject: [PATCH 014/117] Rewrote a confusing sentence --- src/ch04-01-what-is-ownership.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/ch04-01-what-is-ownership.md b/src/ch04-01-what-is-ownership.md index 5012d8614b..cf8fd209b4 100644 --- a/src/ch04-01-what-is-ownership.md +++ b/src/ch04-01-what-is-ownership.md @@ -146,9 +146,9 @@ that is stored on the heap and explore how Rust knows when to clean up that data. We’ll use `String` as the example here and concentrate on the parts of `String` -that relate to ownership. These aspects also apply to other complex data types -provided by the standard library and that you create. We’ll discuss `String` in -more depth in Chapter 8. +that relate to ownership. These aspects also apply to other complex data types, +whether they are provided by the standard library or created by you. We’ll +discuss `String` in more depth in Chapter 8. We’ve already seen string literals, where a string value is hardcoded into our program. String literals are convenient, but they aren’t suitable for every From f749a7488d1025f0f5ea910b690a77ff35da49a3 Mon Sep 17 00:00:00 2001 From: Tom Godkin Date: Sat, 9 Mar 2019 11:33:45 +0000 Subject: [PATCH 015/117] ch07-04: remove note regarding use + relative path --- ...inging-paths-into-scope-with-the-use-keyword.md | 14 +++++--------- 1 file changed, 5 insertions(+), 9 deletions(-) diff --git a/src/ch07-04-bringing-paths-into-scope-with-the-use-keyword.md b/src/ch07-04-bringing-paths-into-scope-with-the-use-keyword.md index 3fcdb4bbe2..83ae1f9a4b 100644 --- a/src/ch07-04-bringing-paths-into-scope-with-the-use-keyword.md +++ b/src/ch07-04-bringing-paths-into-scope-with-the-use-keyword.md @@ -41,10 +41,9 @@ root, `hosting` is now a valid name in that scope, just as though the `hosting` module had been defined in the crate root. Paths brought into scope with `use` also check privacy, like any other paths. -Specifying a relative path with `use` is slightly different. Instead of -starting from a name in the current scope, we must start the path given to -`use` with the keyword `self`. Listing 7-12 shows how to specify a relative -path to get the same behavior as in Listing 7-11. +You can also bring an item into scope with `use` and a relative path. Listing +7-12 shows how to specify a relative path to get the same behavior as in +Listing 7-11. Filename: src/lib.rs @@ -55,7 +54,7 @@ mod front_of_house { } } -use self::front_of_house::hosting; +use front_of_house::hosting; pub fn eat_at_restaurant() { hosting::add_to_waitlist(); @@ -66,10 +65,7 @@ pub fn eat_at_restaurant() { ``` Listing 7-12: Bringing a module into scope with `use` and -a relative path starting with `self` - -Note that using `self` in this way might not be necessary in the future; it’s -an inconsistency in the language that Rust developers are working to eliminate. +a relative path ### Creating Idiomatic `use` Paths From 18b02e169efcfdb30ac5c3b63be751ac5a5c0413 Mon Sep 17 00:00:00 2001 From: BooleanCat Date: Sun, 16 Jun 2019 23:26:13 +0100 Subject: [PATCH 016/117] ch18-03: no need to debug print destructured int --- src/ch18-03-pattern-syntax.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/ch18-03-pattern-syntax.md b/src/ch18-03-pattern-syntax.md index ccdeb6608b..287fae9377 100644 --- a/src/ch18-03-pattern-syntax.md +++ b/src/ch18-03-pattern-syntax.md @@ -711,11 +711,11 @@ fn main() { match x { Some(50) => println!("Got 50"), - Some(n) if n == y => println!("Matched, n = {:?}", n), + Some(n) if n == y => println!("Matched, n = {}", n), _ => println!("Default case, x = {:?}", x), } - println!("at the end: x = {:?}, y = {:?}", x, y); + println!("at the end: x = {:?}, y = {}", x, y); } ``` From 5af8895ec347e2ea4d6ec71e3e6680ec3d9c32f5 Mon Sep 17 00:00:00 2001 From: Joseph Lyons Date: Mon, 17 Jun 2019 00:30:21 -0400 Subject: [PATCH 017/117] Added a bullet point to have list of things unsafe allows for match up with the nomicon https://doc.rust-lang.org/nomicon/what-unsafe-does.html --- src/ch19-01-unsafe-rust.md | 1 + 1 file changed, 1 insertion(+) diff --git a/src/ch19-01-unsafe-rust.md b/src/ch19-01-unsafe-rust.md index 8605ede6a2..8c32b3663e 100644 --- a/src/ch19-01-unsafe-rust.md +++ b/src/ch19-01-unsafe-rust.md @@ -33,6 +33,7 @@ the ability to: * Call an unsafe function or method * Access or modify a mutable static variable * Implement an unsafe trait +* Access fields of `union`s It’s important to understand that `unsafe` doesn’t turn off the borrow checker or disable any other of Rust’s safety checks: if you use a reference in unsafe From b3738eb0de03cce538c3f86a79784f0cbe11f74a Mon Sep 17 00:00:00 2001 From: Zoey Hewll Date: Tue, 18 Jun 2019 13:21:01 +0800 Subject: [PATCH 018/117] Update Ch19.1 on slice splitting resolves issue #1995 --- src/ch19-01-unsafe-rust.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ch19-01-unsafe-rust.md b/src/ch19-01-unsafe-rust.md index 8605ede6a2..b90cc92ba4 100644 --- a/src/ch19-01-unsafe-rust.md +++ b/src/ch19-01-unsafe-rust.md @@ -250,7 +250,7 @@ fn split_at_mut(slice: &mut [i32], mid: usize) -> (&mut [i32], &mut [i32]) { This function first gets the total length of the slice. Then it asserts that the index given as a parameter is within the slice by checking whether it’s less than or equal to the length. The assertion means that if we pass an index -that is greater than the index to split the slice at, the function will panic +that is greater than the length to split the slice at, the function will panic before it attempts to use that index. Then we return two mutable slices in a tuple: one from the start of the From 71fc588d9fec7f1292b588c30e3ae13c5dc54736 Mon Sep 17 00:00:00 2001 From: Tobias Pfeiffer Date: Mon, 24 Jun 2019 11:55:31 +0200 Subject: [PATCH 019/117] Update loose mdbook version reference --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index c47820b795..6dd1d9f373 100644 --- a/README.md +++ b/README.md @@ -19,7 +19,7 @@ releases are updated less frequently. ## Requirements -Building the book requires [mdBook], ideally the same 0.2.x version that +Building the book requires [mdBook], ideally the same 0.3.x version that rust-lang/rust uses in [this file][rust-mdbook]. To get it: [mdBook]: https://github.com/rust-lang-nursery/mdBook From 0df67367cc6db6b1d76734127d1029899dbfe60d Mon Sep 17 00:00:00 2001 From: Russell Dunphy Date: Fri, 5 Jul 2019 10:43:11 +0100 Subject: [PATCH 020/117] Update Readme mdBook version to match linked file --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index c47820b795..6dd1d9f373 100644 --- a/README.md +++ b/README.md @@ -19,7 +19,7 @@ releases are updated less frequently. ## Requirements -Building the book requires [mdBook], ideally the same 0.2.x version that +Building the book requires [mdBook], ideally the same 0.3.x version that rust-lang/rust uses in [this file][rust-mdbook]. To get it: [mdBook]: https://github.com/rust-lang-nursery/mdBook From 311930de8a5f7748c18137603d4f88592d3a5b77 Mon Sep 17 00:00:00 2001 From: Benjamin Lee Date: Mon, 8 Jul 2019 17:49:46 -0700 Subject: [PATCH 021/117] Update ch15-03 code to match output. --- src/ch15-03-drop.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ch15-03-drop.md b/src/ch15-03-drop.md index 800de36bfc..5f717b3982 100644 --- a/src/ch15-03-drop.md +++ b/src/ch15-03-drop.md @@ -146,7 +146,7 @@ an argument. The function is in the prelude, so we can modify `main` in Listing # # impl Drop for CustomSmartPointer { # fn drop(&mut self) { -# println!("Dropping CustomSmartPointer!"); +# println!("Dropping CustomSmartPointer with data `{}`!", self.data); # } # } # From a5a03d8f61a5b2c2111b21031a3f526ef60844dd Mon Sep 17 00:00:00 2001 From: josthoff Date: Tue, 9 Jul 2019 20:11:30 +0200 Subject: [PATCH 022/117] fixed inconsistent terminology regarding enums --- src/ch06-00-enums.md | 2 +- src/ch06-01-defining-an-enum.md | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/ch06-00-enums.md b/src/ch06-00-enums.md index 767f8668da..cf7ea67f60 100644 --- a/src/ch06-00-enums.md +++ b/src/ch06-00-enums.md @@ -1,7 +1,7 @@ # Enums and Pattern Matching In this chapter we’ll look at *enumerations*, also referred to as *enums*. -Enums allow you to define a type by enumerating its possible values. First, +Enums allow you to define a type by enumerating its possible *variants*. First, we’ll define and use an enum to show how an enum can encode meaning along with data. Next, we’ll explore a particularly useful enum, called `Option`, which expresses that a value can be either something or nothing. Then we’ll look at diff --git a/src/ch06-01-defining-an-enum.md b/src/ch06-01-defining-an-enum.md index 9a56af7372..0d25afbb68 100644 --- a/src/ch06-01-defining-an-enum.md +++ b/src/ch06-01-defining-an-enum.md @@ -5,18 +5,18 @@ are useful and more appropriate than structs in this case. Say we need to work with IP addresses. Currently, two major standards are used for IP addresses: version four and version six. These are the only possibilities for an IP address that our program will come across: we can *enumerate* all possible -values, which is where enumeration gets its name. +variants, which is where enumeration gets its name. Any IP address can be either a version four or a version six address, but not both at the same time. That property of IP addresses makes the enum data -structure appropriate, because enum values can only be one of the variants. +structure appropriate, because enum values can only be one of its variants. Both version four and version six addresses are still fundamentally IP addresses, so they should be treated as the same type when the code is handling situations that apply to any kind of IP address. We can express this concept in code by defining an `IpAddrKind` enumeration and -listing the possible kinds an IP address can be, `V4` and `V6`. These are known -as the *variants* of the enum: +listing the possible kinds an IP address can be, `V4` and `V6`. These are the +variants of the enum: ```rust enum IpAddrKind { From 315c48f695e3e75b12347bcf42b09a0d0410c016 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alexander=20Kriv=C3=A1cs=20Schr=C3=B8der?= Date: Thu, 11 Jul 2019 17:32:59 +0200 Subject: [PATCH 023/117] Fix broken link to Chapter 13-01 in Chapter 12-04 --- src/ch12-04-testing-the-librarys-functionality.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/ch12-04-testing-the-librarys-functionality.md b/src/ch12-04-testing-the-librarys-functionality.md index 2d1eeb04d6..e252de1582 100644 --- a/src/ch12-04-testing-the-librarys-functionality.md +++ b/src/ch12-04-testing-the-librarys-functionality.md @@ -196,7 +196,7 @@ pub fn search<'a>(query: &str, contents: &'a str) -> Vec<&'a str> { The `lines` method returns an iterator. We’ll talk about iterators in depth in -[Chapter 13][ch13], but recall that you saw this way of using an +[Chapter 13][ch13-iterators], but recall that you saw this way of using an iterator in [Listing 3-5][ch3-iter], where we used a `for` loop with an iterator to run some code on each item in a collection. @@ -336,3 +336,4 @@ ch10-03-lifetime-syntax.html#validating-references-with-lifetimes [ch11-anatomy]: ch11-01-writing-tests.html#the-anatomy-of-a-test-function [ch10-lifetimes]: ch10-03-lifetime-syntax.html [ch3-iter]: ch03-05-control-flow.html#looping-through-a-collection-with-for +[ch13-iterators]: ch13-02-iterators.html \ No newline at end of file From 9cb1d20394f047855a57228dc4cbbabd0a9b395a Mon Sep 17 00:00:00 2001 From: Vasily Galkin Date: Sun, 14 Jul 2019 16:29:52 +0300 Subject: [PATCH 024/117] Printing non-Display structs is a *compile* error `Rectangle` doesn't implement `std::fmt::Display` is a compile error, not a run-time error. --- src/ch05-02-example-structs.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/ch05-02-example-structs.md b/src/ch05-02-example-structs.md index 4aeb816fe6..46f88f1b8a 100644 --- a/src/ch05-02-example-structs.md +++ b/src/ch05-02-example-structs.md @@ -165,7 +165,7 @@ fn main() { Listing 5-11: Attempting to print a `Rectangle` instance -When we run this code, we get an error with this core message: +When we compile this code, we get an error with this core message: ```text error[E0277]: `Rectangle` doesn't implement `std::fmt::Display` @@ -195,7 +195,7 @@ Let’s try it! The `println!` macro call will now look like `println!("rect1 is enables us to print our struct in a way that is useful for developers so we can see its value while we’re debugging our code. -Run the code with this change. Drat! We still get an error: +Compile the code with this change. Drat! We still get an error: ```text error[E0277]: `Rectangle` doesn't implement `std::fmt::Debug` From 38ceba56a8bf4efaa977000b85b7a9df191cb827 Mon Sep 17 00:00:00 2001 From: Paul Emmerich Date: Sun, 14 Jul 2019 22:25:04 +0200 Subject: [PATCH 025/117] ci: validate that all used references are defined this will catch issues like https://github.com/rust-lang/book/issues/2010 --- ci/build.sh | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/ci/build.sh b/ci/build.sh index 9ad1781381..d8f966f07e 100644 --- a/ci/build.sh +++ b/ci/build.sh @@ -19,3 +19,9 @@ echo 'Building...' mdbook build echo 'Linting for local file paths...' cargo run --bin lfp src +echo 'Validating references' +for file in src/*.md ; do + echo Checking references in $file + cargo run --quiet --bin link2print < $file > /dev/null +done + From 1b006e0ec6d20502ac9949f807685df0bd95d3f2 Mon Sep 17 00:00:00 2001 From: leudz Date: Wed, 17 Jul 2019 20:43:35 +0200 Subject: [PATCH 026/117] add missing Ferris --- src/ch16-02-message-passing.md | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/ch16-02-message-passing.md b/src/ch16-02-message-passing.md index 7cb4cfa8d3..56181eaf79 100644 --- a/src/ch16-02-message-passing.md +++ b/src/ch16-02-message-passing.md @@ -35,12 +35,11 @@ want to send over the channel. Filename: src/main.rs -```rust +```rust,ignore,does_not_compile use std::sync::mpsc; fn main() { let (tx, rx) = mpsc::channel(); -# tx.send(()).unwrap(); } ``` From 7e219336581c41a80fd41f4fbe615fecb6ed0a7d Mon Sep 17 00:00:00 2001 From: Benjamin Lee Date: Tue, 23 Jul 2019 21:58:18 +0800 Subject: [PATCH 027/117] Removed unnecessary & in function call --- src/ch17-03-oo-design-patterns.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ch17-03-oo-design-patterns.md b/src/ch17-03-oo-design-patterns.md index efe3f43943..4ffb3a0179 100644 --- a/src/ch17-03-oo-design-patterns.md +++ b/src/ch17-03-oo-design-patterns.md @@ -380,7 +380,7 @@ otherwise, we want to return an empty string slice, as shown in Listing 17-17: impl Post { // --snip-- pub fn content(&self) -> &str { - self.state.as_ref().unwrap().content(&self) + self.state.as_ref().unwrap().content(self) } // --snip-- } From b5ebb1b7664c733307d1bee38e8c3ad157cf770a Mon Sep 17 00:00:00 2001 From: Benjamin Lee Date: Thu, 25 Jul 2019 21:16:29 +0800 Subject: [PATCH 028/117] Fixes #2039 --- src/ch18-02-refutability.md | 21 +++++++++++++-------- 1 file changed, 13 insertions(+), 8 deletions(-) diff --git a/src/ch18-02-refutability.md b/src/ch18-02-refutability.md index 55cb03812d..a217958e59 100644 --- a/src/ch18-02-refutability.md +++ b/src/ch18-02-refutability.md @@ -10,8 +10,9 @@ a_value` because if the value in the `a_value` variable is `None` rather than Function parameters, `let` statements, and `for` loops can only accept irrefutable patterns, because the program cannot do anything meaningful when -values don’t match. The `if let` and `while let` expressions only accept -refutable patterns, because by definition they’re intended to handle possible +values don’t match. The `if let` and `while let` expressions accept +refutable patterns and irrefutable patterns, but the compiler warns against +irrefutable patterns because by definition they’re intended to handle possible failure: the functionality of a conditional is in its ability to perform differently depending on success or failure. @@ -69,9 +70,9 @@ patterns instead of `let` We’ve given the code an out! This code is perfectly valid, although it means we cannot use an irrefutable pattern without receiving an error. If we give `if let` a pattern that will always match, such as `x`, as shown in Listing 18-10, -it will not compile. +the compiler will give a warning. -```rust,ignore,does_not_compile +```rust,ignore if let x = 5 { println!("{}", x); }; @@ -84,11 +85,15 @@ Rust complains that it doesn’t make sense to use `if let` with an irrefutable pattern: ```text -error[E0162]: irrefutable if-let pattern - --> :2:8 +warning: irrefutable if-let pattern + --> :2:5 + | +2 | / if let x = 5 { +3 | | println!("{}", x); +4 | | }; + | |_^ | -2 | if let x = 5 { - | ^ irrefutable pattern + = note: #[warn(irrefutable_let_patterns)] on by default ``` For this reason, match arms must use refutable patterns, except for the last From 30fe5484f3923617410032d28e86a5afdf4076fb Mon Sep 17 00:00:00 2001 From: Benjamin Lee Date: Mon, 29 Jul 2019 21:14:50 -0700 Subject: [PATCH 029/117] Condensed "patterns" --- src/ch18-02-refutability.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ch18-02-refutability.md b/src/ch18-02-refutability.md index a217958e59..36fa17d48b 100644 --- a/src/ch18-02-refutability.md +++ b/src/ch18-02-refutability.md @@ -11,7 +11,7 @@ a_value` because if the value in the `a_value` variable is `None` rather than Function parameters, `let` statements, and `for` loops can only accept irrefutable patterns, because the program cannot do anything meaningful when values don’t match. The `if let` and `while let` expressions accept -refutable patterns and irrefutable patterns, but the compiler warns against +refutable and irrefutable patterns, but the compiler warns against irrefutable patterns because by definition they’re intended to handle possible failure: the functionality of a conditional is in its ability to perform differently depending on success or failure. From 293fbfc38f5bf2cd1bcfd14d90adf69ebd818bb2 Mon Sep 17 00:00:00 2001 From: Benjamin Lee Date: Tue, 30 Jul 2019 20:15:26 -0700 Subject: [PATCH 030/117] Added second missing dyn --- src/ch20-02-multithreaded.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ch20-02-multithreaded.md b/src/ch20-02-multithreaded.md index 2e64463486..5ca9358c70 100644 --- a/src/ch20-02-multithreaded.md +++ b/src/ch20-02-multithreaded.md @@ -895,7 +895,7 @@ at Listing 20-19. # use std::sync::mpsc; # struct Worker {} -type Job = Box; +type Job = Box; impl ThreadPool { // --snip-- From 0ca4b88f75f8579de87adc2ad36d340709f5ccad Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alexander=20Kriv=C3=A1cs=20Schr=C3=B8der?= Date: Wed, 31 Jul 2019 11:20:27 +0200 Subject: [PATCH 031/117] Fix additional broken link to Chapter 13-01 in Chapter 12-04 --- src/ch12-04-testing-the-librarys-functionality.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/ch12-04-testing-the-librarys-functionality.md b/src/ch12-04-testing-the-librarys-functionality.md index e252de1582..e8ed858dec 100644 --- a/src/ch12-04-testing-the-librarys-functionality.md +++ b/src/ch12-04-testing-the-librarys-functionality.md @@ -266,7 +266,7 @@ At this point, we could consider opportunities for refactoring the implementation of the search function while keeping the tests passing to maintain the same functionality. The code in the search function isn’t too bad, but it doesn’t take advantage of some useful features of iterators. We’ll -return to this example in [Chapter 13][ch13], where we’ll +return to this example in [Chapter 13][ch13-iterators], where we’ll explore iterators in detail, and look at how to improve it. #### Using the `search` Function in the `run` Function @@ -336,4 +336,4 @@ ch10-03-lifetime-syntax.html#validating-references-with-lifetimes [ch11-anatomy]: ch11-01-writing-tests.html#the-anatomy-of-a-test-function [ch10-lifetimes]: ch10-03-lifetime-syntax.html [ch3-iter]: ch03-05-control-flow.html#looping-through-a-collection-with-for -[ch13-iterators]: ch13-02-iterators.html \ No newline at end of file +[ch13-iterators]: ch13-02-iterators.html From 239d99f3592c56e519ea4efb3f9bd7c096ca3d60 Mon Sep 17 00:00:00 2001 From: Benjamin Lee Date: Fri, 2 Aug 2019 23:01:52 -0700 Subject: [PATCH 032/117] Subtle fix to introduce ? on Option --- src/ch09-02-recoverable-errors-with-result.md | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/src/ch09-02-recoverable-errors-with-result.md b/src/ch09-02-recoverable-errors-with-result.md index 85c4192836..e84da9053f 100644 --- a/src/ch09-02-recoverable-errors-with-result.md +++ b/src/ch09-02-recoverable-errors-with-result.md @@ -470,13 +470,13 @@ and returns it. Of course, using `fs::read_to_string` doesn’t give us the opportunity to explain all the error handling, so we did it the longer way first. -#### The `?` Operator Can Only Be Used in Functions That Return `Result` +#### The `?` Operator Can Be Used in Functions That Return `Result` -The `?` operator can only be used in functions that have a return type of +The `?` operator can 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`. +can be a `Result` to be compatible with this `return`. Let’s look at what happens if we use the `?` operator in the `main` function, which you’ll recall has a return type of `()`: @@ -505,8 +505,9 @@ error[E0277]: the `?` operator can only be used in a function that returns ``` This error points out that we’re only allowed to use the `?` operator in a -function that returns `Result`. When you’re writing code in a function -that doesn’t return `Result`, and you want to use `?` when you call other +function that returns `Result` or `Option` or another type that implements +`std::ops::Try`. When you’re writing code in a function +that doesn’t return one of these types, and you want to use `?` when you call other functions that return `Result`, you have two choices to fix this problem. One technique is to change the return type of your function to be `Result` if you have no restrictions preventing that. The other technique is to use From 00135e30f05af0d46e7dcf88052a359ac36ae646 Mon Sep 17 00:00:00 2001 From: Jens Date: Tue, 6 Aug 2019 21:41:38 +0200 Subject: [PATCH 033/117] Update ch15-03-drop.md --- src/ch15-03-drop.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ch15-03-drop.md b/src/ch15-03-drop.md index 800de36bfc..3524c17de3 100644 --- a/src/ch15-03-drop.md +++ b/src/ch15-03-drop.md @@ -84,7 +84,7 @@ functionality. Disabling `drop` isn’t usually necessary; the whole point of th `Drop` trait is that it’s taken care of automatically. Occasionally, however, you might want to clean up a value early. One example is when using smart pointers that manage locks: you might want to force the `drop` method that -releases the lock to run so other code in the same scope can acquire the lock. +releases the lock to run some other code in the same scope can acquire the lock. Rust doesn’t let you call the `Drop` trait’s `drop` method manually; instead you have to call the `std::mem::drop` function provided by the standard library if you want to force a value to be dropped before the end of its scope. From bb5667758476a44d92db034d0243702703d6a67b Mon Sep 17 00:00:00 2001 From: Jimskapt Date: Wed, 7 Aug 2019 14:31:55 +0200 Subject: [PATCH 034/117] :twisted_rightwards_arrows: Merging partial translation of ch03 by @ShinySaana From https://github.com/quadrifoglio/rust-book-fr/tree/fr-ch03/second-edition/src --- FRENCH/src/SUMMARY.md | 7 + .../ch03-00-common-programming-concepts.md | 54 ++ .../src/ch03-01-variables-and-mutability.md | 541 ++++++++++++++ FRENCH/src/ch03-02-data-types.md | 699 ++++++++++++++++++ FRENCH/src/ch03-03-how-functions-work.md | 458 ++++++++++++ FRENCH/src/ch03-04-comments.md | 71 ++ FRENCH/src/ch03-05-control-flow.md | 682 +++++++++++++++++ 7 files changed, 2512 insertions(+) create mode 100644 FRENCH/src/ch03-00-common-programming-concepts.md create mode 100644 FRENCH/src/ch03-01-variables-and-mutability.md create mode 100644 FRENCH/src/ch03-02-data-types.md create mode 100644 FRENCH/src/ch03-03-how-functions-work.md create mode 100644 FRENCH/src/ch03-04-comments.md create mode 100644 FRENCH/src/ch03-05-control-flow.md diff --git a/FRENCH/src/SUMMARY.md b/FRENCH/src/SUMMARY.md index 42c5a7f084..88d2954cdc 100644 --- a/FRENCH/src/SUMMARY.md +++ b/FRENCH/src/SUMMARY.md @@ -1 +1,8 @@ # Le langage de programmation Rust + +- [Les concepts de programmation courants](ch03-00-common-programming-concepts.md) + - [Les variables et la mutabilité](ch03-01-variables-and-mutability.md) + - [Les types de données](ch03-02-data-types.md) + - [Les fonctions](ch03-03-how-functions-work.md) + - [Les commentaires](ch03-04-comments.md) + - [Les structure de contrôle](ch03-05-control-flow.md) diff --git a/FRENCH/src/ch03-00-common-programming-concepts.md b/FRENCH/src/ch03-00-common-programming-concepts.md new file mode 100644 index 0000000000..23008bc97c --- /dev/null +++ b/FRENCH/src/ch03-00-common-programming-concepts.md @@ -0,0 +1,54 @@ + + +# Concepts courants de programmation + + + +Ce chapitre couvre des concepts qui apparaissent dans presque tous les langages +de programmation et la manière dont ils fonctionnent en Rust. De nombreux +langages partagent à la base des concepts communs. Aucun de ceux présentés dans +ce chapitre ne sont uniques à Rust, mais nous en discuterons dans le contexte +de Rust et nous en expliquerons les conventions. + + + +Plus spécifiquement, vous allez apprendre les concepts de variables, de types +de base, de fonctions, de commentaires, et de flot d'exécution. Ces +fondamentaux seront présents dans chaque programme Rust, et les apprendre dès +maintenant vous procurera de solides bases pour débuter. + + + + +> ### Mot-clés +> +> Le langage Rust possède un ensemble de *mot-clés* qui ont été réservés pour +> l'usage exclusif du langage, tout comme le font d'autres langages. Gardez à +> l'esprit que vous ne pouvez pas utiliser ces mots comme noms de variables ou +> de fonctions. La plupart des mots-clés ont une signification spéciale, et +> vous les utiliserez pour réaliser de nombreuses tâches dans vos programmes +> Rust; quelques-uns n'ont pour le moment aucune fonctionnalité leur étant +> associée, mais ont été réservés pour un usage futur. Vous pouvez trouver une +> liste de ces mots-clés dans l'Annexe A. diff --git a/FRENCH/src/ch03-01-variables-and-mutability.md b/FRENCH/src/ch03-01-variables-and-mutability.md new file mode 100644 index 0000000000..e352a5f389 --- /dev/null +++ b/FRENCH/src/ch03-01-variables-and-mutability.md @@ -0,0 +1,541 @@ + + +## Variables et Mutabilité + + + +Comme mentionné dans le Chapitre 2, par défaut, les variables sont *immuables*. +C'est un des nombreux coups de pouces de Rust vous encourageant à écrire votre +code d'une façon à tirer avantage de la sûreté et de la concurrence facilitée +que Rust propose. Cependant, vous avez tout de même la possibilité de rendre +vos variables mutables. Explorons comment et pourquoi Rust vous encourage à +favoriser l'immutabilité, et pourquoi vous pourriez choisir d'y renoncer. + + + +Lorsque qu'une variable est immuable, cela signifie qu'une fois qu'une valeur +est liée à un nom, vous ne pouvez pas changer cette valeur. À titre +d'illustration, générons un nouveau projet appelé *variables* dans votre +dossier *projects* en utilisant `cargo new --bin variables`. + + + +Ensuite, dans votre nouveau dossier *variables*, ouvrez *src/main.rs* et remplacez son contenu par ceci : + + + +Fichier : src/main.rs + + + +```rust,ignore,does_not_compile +fn main() { + let x = 5; + println!("The value of x is: {}", x); + x = 6; + println!("The value of x is: {}", x); +} +``` + + + +Sauvegardez et lancez le programme en utilisant `cargo run`. Vous devriez obtenir un message d'erreur, tel qu'indiqué par la sortie suivante : + + + +```text +error[E0384]: cannot assign twice to immutable variable `x` + --> src/main.rs:4:5 + | +2 | let x = 5; + | - first assignment to `x` +3 | println!("The value of x is: {}", x); +4 | x = 6; + | ^^^^^ cannot assign twice to immutable variable +``` + + + +Cet exemple montre comment le compilateur vous aide à identifier les erreurs +dans vos programmes. Même si les erreurs de compilation peuvent s'avérer +frustrantes, elles signifient uniquement que votre programme n'est pour le +moment pas en train de faire ce que vous voulez qu'il fasse en toute sécurité ; +elles ne signifient *pas* que vous êtes un mauvais en programmation ! Même les +Rustacéens et Rustacéennes ayant de l'expérience continuent d'avoir des erreurs de compilation. + + + +Cette erreur indique que la cause du problème est qu'il est `impossible +d'assigner à deux reprises la variable immuable x`, car nous avons essayé de +donner à `x`, qui est une variable immuable, une seconde valeur. + + + +Il est important que nous obtenions des erreurs lors de la compilation quand +nous essayons de changer une valeur qui a précédemment été désignée comme +immuable, car cette situation précise peut donner lieu à des bugs. Si une +partie de notre code opère sur le postulat qu'une valeur ne changera jamais et +qu'une autre partie de notre code modifie cette valeur, il est possible que la +première partie du code ne fera pas ce pour quoi elle a été conçue. Cette +source d'erreur peut être difficile à identifier après coup, particulièrement +lorsque la seconde partie du code ne modifie que *quelquefois* cette valeur. + + + +En Rust, le compilateur garantie que lorsque nous déclarons qu'une variable ne +changera pas, elle ne changera vraiment pas. Cela signifie que lorsque que vous +lisez et écrivez du code, vous n'avez pas à vous souvenir de comment et où une +valeur pourrait changer, ce qui peut rendre le code plus facile à comprendre. + + + +Mais la mutabilité peut s'avérer très utile. Les variables ne sont seulement +qu'immuables par défaut ; nous pouvons les rendre mutables en ajoutant `mut` +devant notre nom de variable. En plus d'autoriser cette valeur à changer, cela +communique l'intention aux futurs lecteurs de ce code que d'autres parties du +code vont modifier cette valeur variable. + + + +Par exemple, modifions *src/main.rs* par : + + + +Fichier : src/main.rs + + + +```rust +fn main() { + let mut x = 5; + println!("The value of x is: {}", x); + x = 6; + println!("The value of x is: {}", x); +} +``` + + + +Lorsque nous exécutons le programme, nous obtenons : + + + +```text +$ cargo run + Compiling variables v0.1.0 (file:///projects/variables) + Finished dev [unoptimized + debuginfo] target(s) in 0.30 secs + Running `target/debug/variables` +The value of x is: 5 +The value of x is: 6 +``` + + + +En utilisant `mut`, nous sommes autorisés à changer la valeur à laquelle `x` +est reliée de `5` à `6`. Dans certains cas, vous allez vouloir rendre une +variable mutable car cela rend le code plus pratique à écrire qu'une +implémentation n'utilisant que des variables immuables. + + + +Il y a plusieurs compromis à prendre en considération, outre la prévention des +bugs. Par exemple, dans le cas où vous utiliseriez de larges structures de +données, muter une instance déjà existante peut être plus rapide que copier et +retourner une instance nouvellement allouée. Sur des structures de données plus +petites, créer de nouvelles instances et écrire dans un style de programmation +plus fonctionnel peut rendre votre code plus facile à comprendre, ainsi, peut +être qu'un coût plus élevé en performance est un moindre mal face au gain de +clareté apporté. + + + +### Différences Entre Variable et Constante + + + +Être incapable de changer la valeur d'une variable peut vous avoir rappelé un autre concept de programmation que de nombreux autres langages possèdent : les *constantes*. Comme les variables immuables, les constantes sont également des valeurs qui sont liées à un nom et qui ne peuvent être modifiées, mais il y a quelques différences entre les constantes et les variables. + + + +D'abord, nous ne sommes pas autorisés à utiliser `mut` avec les constantes : les constantes ne sont pas seulement immuables par défaut, elles le sont toujours. + + + +Nous déclarons les constantes en utilisant le mot-clé `const` à la place du +mot-clé `let`, et le type de la valeur *doit* être annoté. Nous sommes sur le +point de traiter des types et des annotations de types dans la prochaine +section, “Types de données,” donc ne vous inquiétez pas des détails pour le +moment, rappelez-vous juste que vous devez toujours annoter leur type. + + + +Les constantes peuvent être déclarées dans n'importe quelle portée, y compris +la portée globale, ce qui les rend très utiles pour des valeurs que de +nombreuses parties de votre code ont besoin de connaître. + + + +La dernière différence est que les constantes ne peuvent être définies que par +une expression constante, et non pas le résultat d'un appel de fonction ou +n'importe quelle autre valeur qui ne pourrait être calculée qu'à l'exécution. + + + +Voici un exemple d'une déclaration de constante où le nom de la constante est +MAX_POINTS` et où sa valeur est définie à 100 000 (en Rust, la convention de +nommage des constantes est d'utiliser des majuscules pour chaque lettre et des +tirets bas entre chaque mot) : + +```rust +const MAX_POINTS: u32 = 100_000; +``` + + + +Les constantes sont valables pendant toute la durée d'exécution du programme à +l'intérieur de la portée dans laquelle elles sont déclarées, ce qui en font de +très bon choix lorsque plusieurs parties d'un programme doivent connaître +certaines valeurs, comme par exemple le nombre maximum de points qu'un joueur +est autorisé à gagner ou la vitesse de la lumière. + + + +Déclarer des valeurs codées en dur et utilisées tout le long de votre programme +comme constantes est utile car cela transmet la signification de ces valeurs +aux futurs mainteneurs de votre code. Cela permet également de n'avoir qu'un +seul endroit de votre code à modifier si une valeur codée en dur doit être mise +à jour dans le futur. + + + +### *Shadowing* + + + +Comme nous l'avons vu dans le jeu du Chapitre 2, nous pouvons déclarer de +nouvelles variables avec le même nom qu'une variable précédente, et que la +nouvelle variable *shadow*, occulte la première. Les Rustacéens disent que la +première variable est *shadowed*, occultée par la seconde, ce qui signifie que +la valeur de la seconde variable sera ce que nous obtiendrons lorsque nous +utiliserons cette variable. Nous pouvons occulter une variable en utilisant le +même nom de variable et en réutilisant le mot-clé `let` comme suit : + + + +Fichier : src/main.rs + + + +```rust +fn main() { + let x = 5; + + let x = x + 1; + + let x = x * 2; + + println!("The value of x is: {}", x); +} +``` + + + +En premier lieu, ce programme lie `x` à la valeur `5`. Puis il *shadow* `x` en +répétant `let x =`, ce qui récupère la valeur originelle et lui ajoute `1` : la +valeur de `x` est désormais `6`. La troisième instruction `let` *shadow* +également `x`, prenant la précédente valeur et la multipliant par `2` pour +donner à `x` une valeur finale de `12`. Lorsque nous exécutons ce programme, +nous obtenons en sortie ceci : + + + +```text +$ cargo run + Compiling variables v0.1.0 (file:///projects/variables) + Finished dev [unoptimized + debuginfo] target(s) in 0.31 secs + Running `target/debug/variables` +The value of x is: 12 +``` + + + +Ceci est différent que marquer une variable comme `mut`, car à moins d'utiliser +le mot-clé `let` une nouvelle fois, nous obtenons une erreur de compilation si +nous essayons accidentellement de réassigner cette variable. Nous pouvons +effectuer quelques transformations sur une valeur puis faire en sorte que la +variable soit immuable après que ces transformations soient terminées. + + + +L'autre différence entre le `mut` et le *shadowing* est la création effective +d'une nouvelle variable lorsque nous utilisons le mot-clé `let` une nouvelle +fois, ce qui nous permet de changer le type de la valeur, mais en réutilisant +le même nom. Par exemple, disons que notre programme demande à un utilisateur +le nombre d'espaces à afficher entre du texte en saisissant des caractères +d'espace, mais que nous voulions quand même enregistrer cette saisie comme un +nombre : + + + +```rust +let spaces = " "; +let spaces = spaces.len(); +``` + + + +Cette conception est autorisée car la première variable `spaces` est du type +*string*, alors que la seconde variable `spaces`, qui est une toute nouvelle +variable se trouvant avoir le même nom que la première, est du type nombre. +L'utilisation du *shadowing* nous évite ainsi d'avoir à trouver des noms +différents, comme `spaces_str` et `spaces_num` ; nous pouvons plutôt utiliser +le simple nom de `spaces`. En revanche, si nous essayons d'utiliser `mut` pour +cela, comme montré ci-dessous, nous obtenons une erreur de compilation : + + + +```rust,ignore +let mut spaces = " "; +spaces = spaces.len(); +``` + + + +Cette erreur indique que nous ne pouvons pas muer le type d'une variable : + +```text +error[E0308]: mismatched types + -- > src/main.rs:3:14 + | +3 | spaces = spaces.len(); + | ^^^^^^^^^^^^ expected &str, found usize + | + = note: expected type `&str` + found type `usize` +``` + + + +Maintenant que nous avons exploré comment fonctionnent les variables, étudions +désormais de nouveaux types de données que ces variables peuvent contenir. + +[comparing-the-guess-to-the-secret-number]: +ch02-00-guessing-game-tutorial.html#comparing-the-guess-to-the-secret-number +[data-types]: ch03-02-data-types.html#data-types diff --git a/FRENCH/src/ch03-02-data-types.md b/FRENCH/src/ch03-02-data-types.md new file mode 100644 index 0000000000..f056c9f47e --- /dev/null +++ b/FRENCH/src/ch03-02-data-types.md @@ -0,0 +1,699 @@ + + +## Types de données + + + +Toutes les valeurs en Rust sont d'un certain *type*, qui indique à Rust quels +type de donnée est en train d'être spécifié afin qu'il puisse savoir comment +traiter la donnée. Dans cette section, nous allons nous intéresser à certains +types de données inclus dans langage. Nous divisions habituellement chaque type +dans deux catégories : les scalaires et les composés. + + + +Tout au long de cette section, gardez à l'esprit que Rust est langage +*statiquement typé*, ce qui signifie qu'il doit connaître les types de toutes +les variables lors de la compilation. Le compilateur peut souvent déduire quel +type utiliser en se basant sur la valeur et comment elle est utilisée. Dans les +cas où plusieurs types sont envisageables, comme lorsque nous avons converti +une `String` en un type numérique en utilisant `parse` dans le Chapitre 2, nous +devons ajouter une annotation de type, comme ceci : + + + +```rust +let guess: u32 = "42".parse().expect("Not a number!"); +``` + + + +Si nous n'ajoutons pas l'annotation de type ici, Rust affichera l'erreur +suivante, signifiant que le compilateur a besoin de plus d'informations pour +déterminer quel type nous souhaitons utiliser : + + + +```text +error[E0282]: type annotations needed + --> src/main.rs:2:9 + | +2 | let guess = "42".parse().expect("Not a number!"); + | ^^^^^ + | | + | cannot infer type for `_` + | consider giving `guess` a type +``` + + + +Vous découvrirez différentes annotations de type au fur et à mesure que nous +discuterons des nombreux types de données. + + + +### Types scalaires + + + +Un type *scalaire* représente une seule valeur. Rust possède quatre types +scalaires principaux : les entiers, les nombres à virgule flottante, les +Booléens et les caractères. Vous les reconnaîtrez surement d'autres langages de +programmation, mais allons voir comment ils fonctionnent en Rust. + + + +#### Types entiers + + + +Un *entier* est un nombre sans partie décimale. Nous avons utilisé un entier +plus tôt dans ce chapitre, le type `u32`. Cette déclaration de type indique +que la valeur à laquelle elle est associée doit être un entier non signé +prenant 32 bits d'espace mémoire (le u de `u32` étant un raccourci pour +*unsigned*, "non signé", au contraire du `i32` pouvant prendre des valeurs +négatives, le i signifiant simplement *integer*, "entier"). Le Tableau 3-1 +montre les types d'entiers inclus dans le langage. Chaque variante dans les +colonnes "Signé" et "Non Signé" (par exemple, *i16*) peut être utilisé pour +déclarer le type d'une valeur entière. + + + +Tableau 3-1: Les types d'entier en Rust + + + +| Taille | Signé | Non signé | +|--------|--------|-----------| +| 8-bit | i8 | u8 | +| 16-bit | i16 | u16 | +| 32-bit | i32 | u32 | +| 64-bit | i64 | u64 | +| arch | isize | usize | + + + +Chaque variante peut-être signée ou non-signée et possède une taille explicite. +Signée et non-signée indique s'il est possible ou non d'être négatif ou positif +; en d'autres termes, si l'on peut lui attribuer un signe (signé) ou s'il sera +toujours positif et que l'on peut donc le représenter sans un signe +(non-signé). C'est comme écrire des nombres sur le papier : quand le signe +importe, un nombre est écrit avec un signe plus ou un signe moins ; en +revanche, quand on peut supposer que le nombre est positif, il est écrit sans +son signe. Les nombres signés sont stockés en utilisant le complément à deux +(si vous n'êtes pas sûr de ce qu'est le complément à deux, vous pouvez le +rechercher sur internet ; une telle explication ne fait pas partie de +l'objectif de ce livre). + + + +Chaque variante signée peut stocker des nombres allant de -(2n - 1) +à 2n - 1 - 1 inclus, où `n` est le nombre de bits que cette variante +utilise. Un `i8` peut donc stocker des nombres allant de -(27) à +27 - 1, ce qui est égal à -128 jusqu'à 127. Les variantes non +signées pouvant aller de 0 à 2n - 1, un `u8` peut donc stocker des +nombres allant de 0 à 28 - 1, ce qui équivaut à 0 jusqu'à 255. + + + +De plus, les types `isize` et `usize` dépendent du type d'ordinateur sur lequel +votre programme va s'exécuter: 64-bits si vous utilisez une architecture 64-bit +ou 32-bits si vous utilisez une architecture 32-bit. + + + +Vous pouvez écrire des nombres entiers littérals dans chacune des formes décrites dans le Tableau 3-2. Notez que chaque nombre littéral excepté l'octet accepte un suffixe de type, comme `57u8`, et `_` comme séparateur visuel, par exemple `1_000`. + + + +Tableau 3-2: Les Entiers Littérals en Rust + + + +| Nombre litéral | Exemple | +|------------------------|---------------| +| Décimal | `98_222` | +| Hexadécimal | `0xff` | +| Octal | `0o77` | +| Binaire | `0b1111_0000` | +| Octet (`u8` seulement) | `b'A'` | + + + +Comment pouvez-vous déterminer le type d'entier à utiliser? Si vous n'êtes pas +sûr, les choix par défaut de Rust sont généralement de bons choix, et le type +d'entier par défaut est `i32` : c'est souvent le plus rapide, même sur des +systèmes 64-bit. La principale raison pour laquelle on utilise un `isize` ou un +`usize` serait lorsque que l'on indexe une quelconque collection. + + + + + +#### Types à Virgule Flottante + + + +Rust possède également deux types primitifs pour les *nombres à virgule +flottante*, les nombres à virgule. Les types à virgule flottante de Rust sont +les `f32` et les `f64`, qui ont respectivement une taille de 32 bits et 64 +bits. Le type par défaut est le `f64` car sur nos processeurs modernes un tel +type est quasiment aussi rapide qu'un `f32` mais est capable d'une plus grande +précision. + + + +Voici un exemple montrant un nombre à virgule flottante en action : + + + +Ficher: src/main.rs + +```rust +fn main() { + let x = 2.0; // f64 + + let y: f32 = 3.0; // f32 +} +``` + + + +Les nombres à virgule flottante sont représentés en accord avec le standard +IEEE-754. Le type `f32` est un *float* à simple précision, et le `f64` est à +double précision. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +```rust +fn main() { + let tup: (i32, f64, u8) = (500, 6.4, 1); +} +``` + + + + + + + + + + + + + + + + + + + + + + + + + +```rust +fn main() { + let a = [1, 2, 3, 4, 5]; +} +``` + + + + + + + + + +```rust +let a: [i32; 5] = [1, 2, 3, 4, 5]; +``` + + + + + +```rust +let a = [3; 5]; +``` + + + + + + + + + +```rust +fn main() { + let a = [1, 2, 3, 4, 5]; + + let first = a[0]; + let second = a[1]; +} +``` + + + + + + + + + + + + + +```text +$ cargo run + Compiling arrays v0.1.0 (file:///projects/arrays) + Finished dev [unoptimized + debuginfo] target(s) in 0.31 secs + Running `target/debug/arrays` +thread 'main' panicked at 'index out of bounds: the len is 5 but the index is + 10', src/main.rs:5:19 +note: Run with `RUST_BACKTRACE=1` for a backtrace. +``` + + + + + +[comparing-the-guess-to-the-secret-number]: +ch02-00-guessing-game-tutorial.html#comparing-the-guess-to-the-secret-number +[control-flow]: ch03-05-control-flow.html#control-flow +[strings]: ch08-02-strings.html#storing-utf-8-encoded-text-with-strings +[unrecoverable-errors-with-panic]: ch09-01-unrecoverable-errors-with-panic.html +[wrapping]: ../std/num/struct.Wrapping.html diff --git a/FRENCH/src/ch03-03-how-functions-work.md b/FRENCH/src/ch03-03-how-functions-work.md new file mode 100644 index 0000000000..cc76251085 --- /dev/null +++ b/FRENCH/src/ch03-03-how-functions-work.md @@ -0,0 +1,458 @@ + + + + + + + + + + + + + + + + +```text +$ cargo run + Compiling functions v0.1.0 (file:///projects/functions) + Finished dev [unoptimized + debuginfo] target(s) in 0.28 secs + Running `target/debug/functions` +Hello, world! +Another function. +``` + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +```rust +fn main() { + let y = 6; +} +``` + + + + + + + + + +```rust,ignore,does_not_compile +fn main() { + let x = (let y = 6); +} +``` + + + +```text +$ cargo run + Compiling functions v0.1.0 (file:///projects/functions) +error: expected expression, found statement (`let`) + -- > src/main.rs:2:14 + | +2 | let x = (let y = 6); + | ^^^ + | + = note: variable declaration using `let` is a statement +``` + + + + + + + + + + + + + + + + + + + + + + + + + + + +```rust +let x = 5; +``` + + + + + + + + + + + + + + + + + +```text +error[E0308]: mismatched types + -- > src/main.rs:7:28 + | +7 | fn plus_one(x: i32) -> i32 { + | ____________________________^ +8 | | x + 1; + | | - help: consider removing this semicolon +9 | | } + | |_^ expected i32, found () + | + = note: expected type `i32` + found type `()` +``` + + diff --git a/FRENCH/src/ch03-04-comments.md b/FRENCH/src/ch03-04-comments.md new file mode 100644 index 0000000000..d41bbc250b --- /dev/null +++ b/FRENCH/src/ch03-04-comments.md @@ -0,0 +1,71 @@ + + + + + + +```rust +// hello, world +``` + + + + + + + + + + + + + + + + + + diff --git a/FRENCH/src/ch03-05-control-flow.md b/FRENCH/src/ch03-05-control-flow.md new file mode 100644 index 0000000000..765278c4e3 --- /dev/null +++ b/FRENCH/src/ch03-05-control-flow.md @@ -0,0 +1,682 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +```text +error[E0308]: mismatched types + -- > src/main.rs:4:8 + | +4 | if number { + | ^^^^^^ expected bool, found integral variable + | + = note: expected type `bool` + found type `{integer}` +``` + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +```text +error[E0308]: if and else have incompatible types + -- > src/main.rs:4:18 + | +4 | let number = if condition { + | __________________^ +5 | | 5 +6 | | } else { +7 | | "six" +8 | | }; + | |_____^ expected integral variable, found &str + | + = note: expected type `{integer}` + found type `&str` +``` + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +[comparing-the-guess-to-the-secret-number]: +ch02-00-guessing-game-tutorial.html#comparing-the-guess-to-the-secret-number +[quitting-after-a-correct-guess]: +ch02-00-guessing-game-tutorial.html#quitting-after-a-correct-guess From be5210893d7af9ea01ca255692167529cb117e96 Mon Sep 17 00:00:00 2001 From: Jimskapt Date: Fri, 9 Aug 2019 11:10:30 +0200 Subject: [PATCH 035/117] :ambulance: :arrow_down: Proofreading and updating old translated text of ch03. --- FRENCH/src/SUMMARY.md | 2 +- .../ch03-00-common-programming-concepts.md | 37 ++- .../src/ch03-01-variables-and-mutability.md | 273 ++++++++++-------- FRENCH/src/ch03-02-data-types.md | 178 +++++++----- FRENCH/src/translation-terms.md | 22 ++ 5 files changed, 298 insertions(+), 214 deletions(-) diff --git a/FRENCH/src/SUMMARY.md b/FRENCH/src/SUMMARY.md index 88d2954cdc..8c4c0ef9f0 100644 --- a/FRENCH/src/SUMMARY.md +++ b/FRENCH/src/SUMMARY.md @@ -1,6 +1,6 @@ # Le langage de programmation Rust -- [Les concepts de programmation courants](ch03-00-common-programming-concepts.md) +- [Les concepts courants de programmation](ch03-00-common-programming-concepts.md) - [Les variables et la mutabilité](ch03-01-variables-and-mutability.md) - [Les types de données](ch03-02-data-types.md) - [Les fonctions](ch03-03-how-functions-work.md) diff --git a/FRENCH/src/ch03-00-common-programming-concepts.md b/FRENCH/src/ch03-00-common-programming-concepts.md index 23008bc97c..0d07f9ce2c 100644 --- a/FRENCH/src/ch03-00-common-programming-concepts.md +++ b/FRENCH/src/ch03-00-common-programming-concepts.md @@ -2,7 +2,7 @@ # Common Programming Concepts --> -# Concepts courants de programmation +# Les concepts courants de programmation -Ce chapitre couvre des concepts qui apparaissent dans presque tous les langages -de programmation et la manière dont ils fonctionnent en Rust. De nombreux -langages partagent à la base des concepts communs. Aucun de ceux présentés dans -ce chapitre ne sont uniques à Rust, mais nous en discuterons dans le contexte -de Rust et nous en expliquerons les conventions. +Ce chapitre explique des concepts qui apparaissent dans presque tous les +langages de programmation, et la manière dont ils fonctionnent en Rust. De +nombreux langages sont basés sur des concepts communs. Dans ce chapitre, nous +n'allons présenter aucun concept spécifique à Rust, mais nous les appliquerons +à Rust et nous expliquerons les conventions qui leur sont liés. -Plus spécifiquement, vous allez apprendre les concepts de variables, de types -de base, de fonctions, de commentaires, et de flot d'exécution. Ces -fondamentaux seront présents dans chaque programme Rust, et les apprendre dès -maintenant vous procurera de solides bases pour débuter. +Plus précisément, vous allez apprendre les concepts de variables, les types de +base, les fonctions, les commentaires, et les structures de contrôle. Ces +notions fondamentales seront présentes dans tous les programmes Rust, et les +apprendre dès le début vous procurera de solides bases pour débuter. - -> ### Mot-clés +> #### Mot-clés > -> Le langage Rust possède un ensemble de *mot-clés* qui ont été réservés pour +> Le langage Rust possède un ensemble de *mots-clés* qui ont été réservés pour > l'usage exclusif du langage, tout comme le font d'autres langages. Gardez à -> l'esprit que vous ne pouvez pas utiliser ces mots comme noms de variables ou -> de fonctions. La plupart des mots-clés ont une signification spéciale, et -> vous les utiliserez pour réaliser de nombreuses tâches dans vos programmes -> Rust; quelques-uns n'ont pour le moment aucune fonctionnalité leur étant -> associée, mais ont été réservés pour un usage futur. Vous pouvez trouver une -> liste de ces mots-clés dans l'Annexe A. +> l'esprit que vous ne pouvez pas utiliser ces mots pour des noms de variables +> ou de fonctions. La plupart des mots-clés ont une signification spéciale, et +> vous les utiliserez pour réaliser de différentes tâches dans vos programmes +> Rust; quelques-uns n'ont aucune fonctionnalité active pour le moment, mais ont +> été réservés pour être ajoutés plus tard à Rust. Vous pouvez trouver la liste +> de ces mots-clés dans l'Annexe A. diff --git a/FRENCH/src/ch03-01-variables-and-mutability.md b/FRENCH/src/ch03-01-variables-and-mutability.md index e352a5f389..c313aa9bc5 100644 --- a/FRENCH/src/ch03-01-variables-and-mutability.md +++ b/FRENCH/src/ch03-01-variables-and-mutability.md @@ -2,7 +2,7 @@ ## Variables and Mutability --> -## Variables et Mutabilité +## Les variables et la mutabilité -Comme mentionné dans le Chapitre 2, par défaut, les variables sont *immuables*. -C'est un des nombreux coups de pouces de Rust vous encourageant à écrire votre -code d'une façon à tirer avantage de la sûreté et de la concurrence facilitée -que Rust propose. Cependant, vous avez tout de même la possibilité de rendre -vos variables mutables. Explorons comment et pourquoi Rust vous encourage à -favoriser l'immutabilité, et pourquoi vous pourriez choisir d'y renoncer. +Tel qu'abordé au Chapitre 2, par défaut, les variables sont *immuables*. C'est +un des nombreux coups de pouces de Rust pour écrire votre code de façon à +garantir la sécurité et la concurrence sans problème. Cependant, vous avez quand +même la possibilité de rendre vos variables mutables *(modifiables)*. Explorons +comment et pourquoi Rust vous encourage à favoriser l'immutabilité, et pourquoi +parfois vous pourriez choisir d'y renoncer. -Lorsque qu'une variable est immuable, cela signifie qu'une fois qu'une valeur -est liée à un nom, vous ne pouvez pas changer cette valeur. À titre -d'illustration, générons un nouveau projet appelé *variables* dans votre -dossier *projects* en utilisant `cargo new --bin variables`. +Lorsqu'une variable est immuable, cela signifie qu'une fois qu'une valeur est +liée à un nom, vous ne pouvez pas changer cette valeur. À titre d'illustration, +générons un nouveau projet appelé *variables* dans votre dossier *projects* en +utilisant `cargo new variables`. -Ensuite, dans votre nouveau dossier *variables*, ouvrez *src/main.rs* et remplacez son contenu par ceci : +Ensuite, dans votre nouveau dossier *variables*, ouvrez *src/main.rs* et +remplacez son code par le code suivant qui ne compile pas pour le moment : -Fichier : src/main.rs +Nom du fichier : src/main.rs -Sauvegardez et lancez le programme en utilisant `cargo run`. Vous devriez obtenir un message d'erreur, tel qu'indiqué par la sortie suivante : +Sauvegardez et lancez le programme en utilisant `cargo run`. Vous devriez +avoir un message d'erreur comme celui-ci : -Cet exemple montre comment le compilateur vous aide à identifier les erreurs -dans vos programmes. Même si les erreurs de compilation peuvent s'avérer -frustrantes, elles signifient uniquement que votre programme n'est pour le -moment pas en train de faire ce que vous voulez qu'il fasse en toute sécurité ; -elles ne signifient *pas* que vous êtes un mauvais en programmation ! Même les -Rustacéens et Rustacéennes ayant de l'expérience continuent d'avoir des erreurs de compilation. +Cet exemple montre comment le compilateur vous aide à trouver les erreurs dans +vos programmes. Même si les erreurs de compilation peuvent s'avérer frustrantes, +elles signifient uniquement que pour le moment, votre programme n'est pas en +train de faire ce que vous voulez qu'il fasse en toute sécurité; elles ne +signifient *pas* que vous êtes un mauvais développeur ! Même les *Rustacés* +expérimentés continuent d'avoir des erreurs de compilation. -Cette erreur indique que la cause du problème est qu'il est `impossible -d'assigner à deux reprises la variable immuable x`, car nous avons essayé de -donner à `x`, qui est une variable immuable, une seconde valeur. +Ce message d'erreur indique que la cause du problème est qu'il est *impossible +d'assigner à deux reprises la variable immuable x* (`cannot assign twice to +immutable variable x`). -Il est important que nous obtenions des erreurs lors de la compilation quand -nous essayons de changer une valeur qui a précédemment été désignée comme -immuable, car cette situation précise peut donner lieu à des bugs. Si une -partie de notre code opère sur le postulat qu'une valeur ne changera jamais et +Il est important que nous obtenions des erreurs au moment de la compilation +lorsque nous essayons de changer une valeur qui a précédemment été déclarée +comme immuable, car cette situation particulière peut donner lieu à des bogues. +Si une partie de notre code par du principe qu'une valeur ne changera jamais et qu'une autre partie de notre code modifie cette valeur, il est possible que la -première partie du code ne fera pas ce pour quoi elle a été conçue. Cette -source d'erreur peut être difficile à identifier après coup, particulièrement +première partie du code ne fasse pas ce pourquoi elle a été conçue. Cette +source d'erreur peut être difficile à identifier après le bogue, en particulier lorsque la seconde partie du code ne modifie que *quelquefois* cette valeur. -En Rust, le compilateur garantie que lorsque nous déclarons qu'une variable ne -changera pas, elle ne changera vraiment pas. Cela signifie que lorsque que vous -lisez et écrivez du code, vous n'avez pas à vous souvenir de comment et où une -valeur pourrait changer, ce qui peut rendre le code plus facile à comprendre. +Avec Rust, le compilateur garantit que lorsque nous déclarons qu'une variable ne +changera pas, elle ne changera vraiment pas. Cela signifie que lorsque vous +lisez et écrivez du code, vous n'avez pas à vous soucier de où et comment la +valeur pourrait changer. Votre code est ainsi plus facile à comprendre. -Mais la mutabilité peut s'avérer très utile. Les variables ne sont seulement -qu'immuables par défaut ; nous pouvons les rendre mutables en ajoutant `mut` -devant notre nom de variable. En plus d'autoriser cette valeur à changer, cela -communique l'intention aux futurs lecteurs de ce code que d'autres parties du -code vont modifier cette valeur variable. +Mais la mutabilité peut s'avérer très utile. Les variables sont immuables par +défaut; mais comme vous l'avez fait au chapitre 2, vous pouvez les rendre +mutables en ajoutant `mut` devant le nom de la variable. En plus de permettre +cette valeur de changer, `mut` va signaler l'intention aux futurs lecteurs de ce +code que d'autres parties du code vont modifier la valeur de cette variable. -Par exemple, modifions *src/main.rs* par : +Par exemple, modifions *src/main.rs* par : -Fichier : src/main.rs +Nom du fichier : src/main.rs -Lorsque nous exécutons le programme, nous obtenons : +Lorsque nous exécutons le programme, nous obtenons : -En utilisant `mut`, nous sommes autorisés à changer la valeur à laquelle `x` -est reliée de `5` à `6`. Dans certains cas, vous allez vouloir rendre une -variable mutable car cela rend le code plus pratique à écrire qu'une -implémentation n'utilisant que des variables immuables. +En utilisant `mut`, nous avons autorisé le changement valeur de `x`, `5` à `6`. +Dans d'autres cas, vous allez vouloir rendre une variable mutable car cela +rendra le code plus pratique à écrire que s'il n'utilisait que des variables +immuables. -Il y a plusieurs compromis à prendre en considération, outre la prévention des -bugs. Par exemple, dans le cas où vous utiliseriez de larges structures de -données, muter une instance déjà existante peut être plus rapide que copier et -retourner une instance nouvellement allouée. Sur des structures de données plus -petites, créer de nouvelles instances et écrire dans un style de programmation -plus fonctionnel peut rendre votre code plus facile à comprendre, ainsi, peut -être qu'un coût plus élevé en performance est un moindre mal face au gain de -clareté apporté. +Il y a d'autres compromis à accepter, en plus de la prévention des bogues. Par +exemple, dans le cas où vous utiliseriez des grosses structures de données, +muter une instance déjà existante peut être plus rapide que copier et retourner +une instance nouvellement allouée. Avec des structures de données plus petites, +créer de nouvelles instances avec un style de programmation fonctionnelle peut +rendre le code plus facile à comprendre, mais il a été ainsi décidé que la +clarté du code est plus importante que le coût en performances. -### Différences Entre Variable et Constante +### Différences entre les variables et les constantes -Être incapable de changer la valeur d'une variable peut vous avoir rappelé un autre concept de programmation que de nombreux autres langages possèdent : les *constantes*. Comme les variables immuables, les constantes sont également des valeurs qui sont liées à un nom et qui ne peuvent être modifiées, mais il y a quelques différences entre les constantes et les variables. +Rendre impossible de changer la valeur d'une variable peut vous avoir rappelé un +autre concept de programmation que de nombreux autres langages possèdent : les +*constantes*. Comme les variables immuables, les constantes sont des valeurs qui +sont liées à un nom et qui ne peuvent être modifiées, mais il y a quelques +différences entre les constantes et les variables. -D'abord, nous ne sommes pas autorisés à utiliser `mut` avec les constantes : les constantes ne sont pas seulement immuables par défaut, elles le sont toujours. +D'abord, vous ne pouvez pas utiliser `mut` avec les constantes. Les constantes +ne sont pas seulement immuables par défaut, elles le sont toujours. Nous déclarons les constantes en utilisant le mot-clé `const` à la place du -mot-clé `let`, et le type de la valeur *doit* être annoté. Nous sommes sur le -point de traiter des types et des annotations de types dans la prochaine -section, “Types de données,” donc ne vous inquiétez pas des détails pour le -moment, rappelez-vous juste que vous devez toujours annoter leur type. +mot-clé `let`, et le type de la valeur *doit* être indiqué. Nous allons aborder +les types et les annotations de types dans la prochaine section, +[“Les types de données”][data-types], donc ne vous souciez pas +des détails pour le moment. Sachez seulement que vous devez toujours indiquer le +type. -Les constantes peuvent être déclarées dans n'importe quelle portée, y compris -la portée globale, ce qui les rend très utiles pour des valeurs que de +Les constantes peuvent être déclarées dans n'importe quel endroit du code, y +compris la portée globale, ce qui les rend très utiles pour des valeurs que de nombreuses parties de votre code ont besoin de connaître. La dernière différence est que les constantes ne peuvent être définies que par -une expression constante, et non pas le résultat d'un appel de fonction ou -n'importe quelle autre valeur qui ne pourrait être calculée qu'à l'exécution. +une expression constante, et non pas le résultat d'un appel de fonction ou toute +autre valeur qui ne pourrait être calculée qu'à l'exécution. -Voici un exemple d'une déclaration de constante où le nom de la constante est -MAX_POINTS` et où sa valeur est définie à 100 000 (en Rust, la convention de -nommage des constantes est d'utiliser des majuscules pour chaque lettre et des -tirets bas entre chaque mot) : +Voici un exemple d'une déclaration de constante où le nom de la constante est +MAX_POINTS` et où sa valeur est définie à 100 000 (avec Rust, la convention de +nommage des constantes est de les écrire toute en majuscule avec des tirets bas +entre les mots, et des tirets bas peuvent être ajoutés entre les nombres pour +améliorer la lisibilité) : ```rust const MAX_POINTS: u32 = 100_000; @@ -335,7 +343,7 @@ Les constantes sont valables pendant toute la durée d'exécution du programme l'intérieur de la portée dans laquelle elles sont déclarées, ce qui en font de très bon choix lorsque plusieurs parties d'un programme doivent connaître certaines valeurs, comme par exemple le nombre maximum de points qu'un joueur -est autorisé à gagner ou la vitesse de la lumière. +est autorisé à gagner ou encore la vitesse de la lumière. Déclarer des valeurs codées en dur et utilisées tout le long de votre programme -comme constantes est utile car cela transmet la signification de ces valeurs -aux futurs mainteneurs de votre code. Cela permet également de n'avoir qu'un -seul endroit de votre code à modifier si une valeur codée en dur doit être mise -à jour dans le futur. +en tant que constantes est utile pour faire comprendre la signification de ces +valeurs dans votre code aux futurs développeurs. Cela permet également de +n'avoir qu'un seul endroit de votre code à modifier si cette valeur codée en dur +doit être mise à jour à l'avenir. -Comme nous l'avons vu dans le jeu du Chapitre 2, nous pouvons déclarer de -nouvelles variables avec le même nom qu'une variable précédente, et que la -nouvelle variable *shadow*, occulte la première. Les Rustacéens disent que la -première variable est *shadowed*, occultée par la seconde, ce qui signifie que -la valeur de la seconde variable sera ce que nous obtiendrons lorsque nous -utiliserons cette variable. Nous pouvons occulter une variable en utilisant le -même nom de variable et en réutilisant le mot-clé `let` comme suit : +Comme nous l'avons vu dans la section +[“Comparer le nombre saisi avec le nombre secret”][comparing-the-guess-to-the-secret-number] +du jeu de devinettes au chapitre 2, nous pouvons déclarer de nouvelles variables +avec le même nom qu'une variable précédente, et que la nouvelle variable sera un +fantôme de la première. Les Rustacés disent que la première variable est *un +fantôme* de la seconde, ce qui signifie que la valeur de la seconde variable +sera ce que nous obtiendrons lorsque nous utiliserons cette variable. Nous +pouvons créer un fantôme d'une variable en utilisant le même nom de variable et +en réutilisant le mot-clé `let` comme ci-dessous : -Fichier : src/main.rs +Nom du fichier : src/main.rs -En premier lieu, ce programme lie `x` à la valeur `5`. Puis il *shadow* `x` en -répétant `let x =`, ce qui récupère la valeur originelle et lui ajoute `1` : la -valeur de `x` est désormais `6`. La troisième instruction `let` *shadow* -également `x`, prenant la précédente valeur et la multipliant par `2` pour -donner à `x` une valeur finale de `12`. Lorsque nous exécutons ce programme, -nous obtenons en sortie ceci : +Au début, ce programme lie `x` à la valeur `5`. Puis il crée un fantôme de `x` +en répétant `let x =`, ce qui récupère la valeur originale et lui ajoute `1` : +la valeur de `x` est désormais `6`. La troisième instruction `let` crée un autre +fantôme de `x`, en récupérant la précédente valeur et en la multipliant par `2` +pour donner à `x` la valeur finale de `12`. Lorsque nous exécutons ce programme, +nous obtenons ceci : -Ceci est différent que marquer une variable comme `mut`, car à moins d'utiliser -le mot-clé `let` une nouvelle fois, nous obtenons une erreur de compilation si -nous essayons accidentellement de réassigner cette variable. Nous pouvons -effectuer quelques transformations sur une valeur puis faire en sorte que la -variable soit immuable après que ces transformations soient terminées. +La création de fantôme est différente que de marquer une variable comme `mut`, +car à moins d'utiliser une nouvelle fois le mot-clé `let`, nous obtiendrons une +erreur de compilation si nous essayons de réassigner cette variable oar +accident. Nous pouvons effectuer quelques transformations sur une valeur avec +`let`, mais la variable doit être immuable après que ces transformations ont été +appliquées. -L'autre différence entre le `mut` et le *shadowing* est la création effective -d'une nouvelle variable lorsque nous utilisons le mot-clé `let` une nouvelle -fois, ce qui nous permet de changer le type de la valeur, mais en réutilisant -le même nom. Par exemple, disons que notre programme demande à un utilisateur -le nombre d'espaces à afficher entre du texte en saisissant des caractères -d'espace, mais que nous voulions quand même enregistrer cette saisie comme un -nombre : +Comme nous créons une nouvelle variable lorsque nous utilisons le mot-clé `let` +une nouvelle fois, l'autre différence entre le `mut` et la création de fantôme +est que cela nous permet de changer le type de la valeur, mais en réutilisant +le même nom. Par exemple, imaginons un programme qui affiche le nombre d'espaces +que saisit l'utilisateur, mais que nous voulons vraiment enregistrer cela sous +forme de nombre : ```rust -let spaces = " "; -let spaces = spaces.len(); +let espaces = " "; +let espaces = espaces.len(); ``` -Cette conception est autorisée car la première variable `spaces` est du type -*string*, alors que la seconde variable `spaces`, qui est une toute nouvelle -variable se trouvant avoir le même nom que la première, est du type nombre. -L'utilisation du *shadowing* nous évite ainsi d'avoir à trouver des noms -différents, comme `spaces_str` et `spaces_num` ; nous pouvons plutôt utiliser -le simple nom de `spaces`. En revanche, si nous essayons d'utiliser `mut` pour -cela, comme montré ci-dessous, nous obtenons une erreur de compilation : +Cette solution est autorisée car la première variable `espaces` est du type +chaîne de caractères *(string)*, alors que la seconde variable `espaces`, qui +est une toute nouvelle variable qui se trouve avoir le même nom que la première, +est du type nombre. L'utilisation de fantômes nous évite ainsi d'avoir à trouver +des noms différents, comme `espaces_str` et `espaces_num` ; nous pouvons plutôt +simplement utiliser le nom de `espaces`. Cependant, si nous essayons d'utiliser +`mut` pour faire ceci, comme ci-dessous, nous avons une erreur de compilation : ```rust,ignore -let mut spaces = " "; -spaces = spaces.len(); +let mut espaces = " "; +espaces = espaces.len(); ``` -Cette erreur indique que nous ne pouvons pas muer le type d'une variable : +Cette erreur indique que nous ne pouvons pas muter le type d'une variable : + + +```text +error[E0308]: mismatched types + -- > src/main.rs:3:14 + | +3 | espaces = espaces.len(); + | ^^^^^^^^^^^^^ expected &str, found usize + | + = note: expected type `&str` + found type `usize` +``` -Maintenant que nous avons exploré comment fonctionnent les variables, étudions -désormais de nouveaux types de données que ces variables peuvent contenir. +Maintenant que nous avons découvert comment fonctionnent les variables, étudions +désormais les types de données qu'elles peuvent contenir. + + +[comparing-the-guess-to-the-secret-number]: +ch02-00-guessing-game-tutorial.html#comparer-le-nombre-saisi-avec-le-nombre-secret +[data-types]: ch03-02-data-types.html#les-types-de-données diff --git a/FRENCH/src/ch03-02-data-types.md b/FRENCH/src/ch03-02-data-types.md index f056c9f47e..c57cf19032 100644 --- a/FRENCH/src/ch03-02-data-types.md +++ b/FRENCH/src/ch03-02-data-types.md @@ -2,7 +2,7 @@ ## Data Types --> -## Types de données +## Les types de données -Toutes les valeurs en Rust sont d'un certain *type*, qui indique à Rust quels -type de donnée est en train d'être spécifié afin qu'il puisse savoir comment -traiter la donnée. Dans cette section, nous allons nous intéresser à certains -types de données inclus dans langage. Nous divisions habituellement chaque type -dans deux catégories : les scalaires et les composés. +Chaque valeur en Rust est d'un *type* bien déterminé, qui indique à Rust quel +type de données il manipule afin qu'il puisse savoir comment travailler avec. +Nous allons nous intéresser à deux catégories de types de données : les +scalaires et les composés. -Tout au long de cette section, gardez à l'esprit que Rust est langage -*statiquement typé*, ce qui signifie qu'il doit connaître les types de toutes -les variables lors de la compilation. Le compilateur peut souvent déduire quel -type utiliser en se basant sur la valeur et comment elle est utilisée. Dans les -cas où plusieurs types sont envisageables, comme lorsque nous avons converti -une `String` en un type numérique en utilisant `parse` dans le Chapitre 2, nous -devons ajouter une annotation de type, comme ceci : +Gardez à l'esprit que Rust est langage *statiquement typé*, ce qui signifie +qu'il doit connaître les types de toutes les variables au moment de la +compilation. Le compilateur peut souvent déduire quel type utiliser en se basant +sur la valeur et comment elle est utilisée. Dans les cas où plusieurs types sont +envisageables, comme lorsque nous avons converti une chaîne de caractères en un +type numérique en utilisant `parse` dans la section +[“Comparer le nombre saisi avec le nombre secret”][comparing-the-guess-to-the-secret-number] ```rust -let guess: u32 = "42".parse().expect("Not a number!"); +let deduction: u32 = "42".parse().expect("Ce n'est pas un nombre !"); ``` src/main.rs:2:9 | -2 | let guess = "42".parse().expect("Not a number!"); - | ^^^^^ +2 | let deduction = "42".parse().expect("Ce n'est pas un nombre !"); + | ^^^^^^^^^ | | | cannot infer type for `_` - | consider giving `guess` a type + | consider giving `deduction` a type ``` Vous découvrirez différentes annotations de type au fur et à mesure que nous -discuterons des nombreux types de données. +aborderons les autres types de données. Un type *scalaire* représente une seule valeur. Rust possède quatre types -scalaires principaux : les entiers, les nombres à virgule flottante, les -Booléens et les caractères. Vous les reconnaîtrez surement d'autres langages de -programmation, mais allons voir comment ils fonctionnent en Rust. +principaux de scalaires : les entiers, les nombres à virgule flottante, les +booléens et les caractères. Vous les connaissez surement d'autres langages de +programmation. Regardons comment ils fonctionnent avec Rust. -#### Types entiers +#### Types de nombres entiers Un *entier* est un nombre sans partie décimale. Nous avons utilisé un entier -plus tôt dans ce chapitre, le type `u32`. Cette déclaration de type indique -que la valeur à laquelle elle est associée doit être un entier non signé -prenant 32 bits d'espace mémoire (le u de `u32` étant un raccourci pour -*unsigned*, "non signé", au contraire du `i32` pouvant prendre des valeurs -négatives, le i signifiant simplement *integer*, "entier"). Le Tableau 3-1 -montre les types d'entiers inclus dans le langage. Chaque variante dans les -colonnes "Signé" et "Non Signé" (par exemple, *i16*) peut être utilisé pour -déclarer le type d'une valeur entière. +précédemment dans le chapitre 2, le type `u32`. Cette déclaration de type +indique que la valeur à laquelle elle est associée doit être un entier non signé +encodé sur 32 bits dans la mémoire (les entiers pouvant prendre des valeurs +négatives commencent par un `i`, le i signifiant *integer* (entier), au lieu du +`u`, le u signifiant *unsigned* : "non signé"). Le Tableau 3-1 montre les types +d'entiers intégrés au langage. Chaque variante dans les colonnes "Signé" et +"Non Signé" (par exemple `i16`) peut être utilisé pour déclarer le type d'une +valeur entière. -Tableau 3-1: Les types d'entier en Rust +Tableau 3-1 : les types d'entier dans Rust -| Taille | Signé | Non signé | -|--------|--------|-----------| -| 8-bit | i8 | u8 | -| 16-bit | i16 | u16 | -| 32-bit | i32 | u32 | -| 64-bit | i64 | u64 | -| arch | isize | usize | +| Taille | Signé | Non signé | +|---------|---------|-----------| +| 8-bit | `i8` | `u8` | +| 16-bit | `i16` | `u16` | +| 32-bit | `i32` | `u32` | +| 64-bit | `i64` | `u64` | +| 128-bit | `i128` | `u128` | +| arch | `isize` | `usize` | Chaque variante peut-être signée ou non-signée et possède une taille explicite. -Signée et non-signée indique s'il est possible ou non d'être négatif ou positif -; en d'autres termes, si l'on peut lui attribuer un signe (signé) ou s'il sera -toujours positif et que l'on peut donc le représenter sans un signe -(non-signé). C'est comme écrire des nombres sur le papier : quand le signe -importe, un nombre est écrit avec un signe plus ou un signe moins ; en -revanche, quand on peut supposer que le nombre est positif, il est écrit sans -son signe. Les nombres signés sont stockés en utilisant le complément à deux -(si vous n'êtes pas sûr de ce qu'est le complément à deux, vous pouvez le -rechercher sur internet ; une telle explication ne fait pas partie de -l'objectif de ce livre). +*Signée* et *non-signée* veut dire respectivement que le nombre est possible ou +non d'être négatif et positif — en d'autres termes, si l'on peut lui attribuer +un signe (signé) ou s'il sera toujours positif et que l'on peut donc le +représenter sans un signe (non-signé). C'est comme écrire des nombres sur un +papier : quand le signe est important, le nombre est écrit avec un signe plus +ou un signe moins ; en revanche, quand le nombre est positif, on peut l'écrire +sans son signe. Les nombres signés sont stockés en utilisant un [complément à +deux](https://fr.wikipedia.org/wiki/Compl%C3%A9ment_%C3%A0_deux). De plus, les types `isize` et `usize` dépendent du type d'ordinateur sur lequel -votre programme va s'exécuter: 64-bits si vous utilisez une architecture 64-bit +votre programme va s'exécuter : 64-bits si vous utilisez une architecture 64-bit ou 32-bits si vous utilisez une architecture 32-bit. -Vous pouvez écrire des nombres entiers littérals dans chacune des formes décrites dans le Tableau 3-2. Notez que chaque nombre littéral excepté l'octet accepte un suffixe de type, comme `57u8`, et `_` comme séparateur visuel, par exemple `1_000`. +Vous pouvez écrire des entiers littéraux dans chacune des formes décrites dans +le Tableau 3-2. Notez que chaque nombre littéral excepté l'octet accepte un +suffixe de type, comme `57u8`, et `_` comme séparateur visuel, comme par exemple +`1_000`. -Tableau 3-2: Les Entiers Littérals en Rust +Tableau 3-2: Les entiers littéraux en Rust -| Nombre litéral | Exemple | +| Nombre littéral | Exemple | |------------------------|---------------| | Décimal | `98_222` | | Hexadécimal | `0xff` | @@ -240,11 +242,11 @@ type is generally the fastest, even on 64-bit systems. The primary situation in which you’d use `isize` or `usize` is when indexing some sort of collection. --> -Comment pouvez-vous déterminer le type d'entier à utiliser? Si vous n'êtes pas +Comment pouvez-vous déterminer le type d'entier à utiliser ? Si vous n'êtes pas sûr, les choix par défaut de Rust sont généralement de bons choix, et le type -d'entier par défaut est `i32` : c'est souvent le plus rapide, même sur des -systèmes 64-bit. La principale raison pour laquelle on utilise un `isize` ou un -`usize` serait lorsque que l'on indexe une quelconque collection. +d'entier par défaut est le `i32` : c'est souvent le plus rapide, même sur des +systèmes 64-bit. La principale utilisation d'un `isize` ou d'un `usize` est +lorsque l'on indexe une quelconque collection. +> ##### Dépassement d'entier +> +> Imaginons que vous avez une variable de type `u8` qui peut stocker des +> valeurs entre 0 et 255. Si vous essayez de changer la variable pour une valeur +> en dehors de cette intervalle, comme 256, vous allez faire un dépassement +> d'entier *(integer overflow)*. Rust embarque quelques règles intéressantes +> concernant ce comportement. Quand vous compilez en mode déboguage, Rust +> embarque des vérifications pour détecter les cas de dépassements d'entiers qui +> pourraient faire *paniquer* votre programme à l'exécution si ce phénomène se +> produit. Rust utilise utilise le terme paniquer quand un programme se termine +> avec une erreur; nous verrons plus en détail les *paniques* dans une section +> du [chapitre 9](ch09-01-unrecoverable-errors-with-panic.html). +> +> Lorsque vous compilez en mode publication *(release)* avec le drapeau +> `--release`, Rust ne va *pas* vérifier les potentiels dépassements d'entier +> qui peuvent faire paniquer le programme. En revanche, en cas de dépassement, +> Rust va effectuer un *rebouclage du complément à deux*. Pour faire simple, les +> valeurs supérieures la valeur maximale du type sera "enroulé" depuis la +> valeur minimale que le type peut stocker. Dans cas d'un `u8`, 256 devient 0, +> 257 devient 1, et ainsi de suite. Le programme ne va pas faire de panic, mais +> la variable va avoir une valeur qui n'est probablement pas ce que vous +> attendez à avoir. Le fait de se fier au comportement de *l'enroulage lors du +> dépassement d'entier* est considéré comme une faute. Si vous voulez enrouler +> explicitement, vous pouvez utiliser le type [`Wrapping`][wrapping] de la +> bibliothèque standard. + -#### Types à Virgule Flottante +#### Types de nombres à virgule flottante Rust possède également deux types primitifs pour les *nombres à virgule -flottante*, les nombres à virgule. Les types à virgule flottante de Rust sont -les `f32` et les `f64`, qui ont respectivement une taille de 32 bits et 64 -bits. Le type par défaut est le `f64` car sur nos processeurs modernes un tel -type est quasiment aussi rapide qu'un `f32` mais est capable d'une plus grande -précision. +flottante*, qui sont des nombres avec des décimales. Les types à virgule +flottante avec Rust sont les `f32` et les `f64`, qui ont respectivement une +taille en mémoire de 32 bits et 64 bits. Le type par défaut est le `f64` car sur +les processeurs récents ce type est quasiment aussi rapide qu'un `f32` mais est +plus précis. -Voici un exemple montrant un nombre à virgule flottante en action : +Voici un exemple montrant l'utilisation d'un nombre à virgule flottante : -Ficher: src/main.rs +Nom du ficher: src/main.rs ```rust fn main() { @@ -316,9 +344,9 @@ Floating-point numbers are represented according to the IEEE-754 standard. The `f32` type is a single-precision float, and `f64` has double precision. --> -Les nombres à virgule flottante sont représentés en accord avec le standard -IEEE-754. Le type `f32` est un *float* à simple précision, et le `f64` est à -double précision. +Les nombres à virgule flottante sont représentés selon le standard IEEE-754. Le +type `f32` est un nombre à virgule flottante à simple précision, et le `f64` est +à double précision. + + +[comparing-the-guess-to-the-secret-number]: +ch02-00-guessing-game-tutorial.html#comparer-le-nombre-saisi-avec-le-nombre-secret + [control-flow]: ch03-05-control-flow.html#control-flow [strings]: ch08-02-strings.html#storing-utf-8-encoded-text-with-strings -[unrecoverable-errors-with-panic]: ch09-01-unrecoverable-errors-with-panic.html [wrapping]: ../std/num/struct.Wrapping.html diff --git a/FRENCH/src/translation-terms.md b/FRENCH/src/translation-terms.md index 2768fc0461..7a97437c9a 100644 --- a/FRENCH/src/translation-terms.md +++ b/FRENCH/src/translation-terms.md @@ -5,6 +5,8 @@ Voici les principaux termes techniques qui ont été traduits de l'Anglais vers | Anglais | Français | Observation(s) | | ------- | ------ | ------ | | ahead-of-time compiled language | langage compilé à la volée | - | +| allocated | alloué | - | +| annotate | indiquer | - | | Application Programming Interface (API) | interface de programmation applicative (API) | - | | arguments | arguments/paramètres | - | | arms | branches | explication de match | @@ -19,13 +21,17 @@ Voici les principaux termes techniques qui ont été traduits de l'Anglais vers | catchall value | valeur passe-partout | - | | closures | fermetures | - | | code review | revue de code | - | +| collection | collection | - | | commit | commit | - | +| compound | composés | - | | concept chapters | chapitres théoriques | - | | concurrency | concurrence | - | | concurrent | concurrent | - | +| constant | constante | - | | control flow construct | structure de contrôle | - | | core of the error | message d'erreur | - | | corruption | être corrompu | - | +| CPU | processeur | - | | crashes | plantages | - | | crates | crates | - | | curly brackets | accolades | - | @@ -38,13 +44,19 @@ Voici les principaux termes techniques qui ont été traduits de l'Anglais vers | exploits | failles | - | | expression | expression | explication de match | | flag | drapeau | (pour les lignes de commande / CLI) | +| float | nombre à virgule flottante | - | +| floating-point number | nombre à virgule flottante | - | +| functional programming | programmation fonctionnelle | - | | generics | génériques | - | +| global scope | portée globale | - | | guessing game | jeu de devinettes | - | | handle | référence | - | | hash | hachage | - | | hash maps | tables de hachage | - | | Hello, world! | Hello, world! | - | | high-level | haut-niveau | - | +| integer literal | entiers littéral | - | +| integer overflow | dépassement d'entier | - | | Integrated Development Environment (IDE) | Integrated Development Environment (IDE) | - | | IOT | internet des objets (IOT) | - | | immutable | immuable | - | @@ -60,9 +72,11 @@ Voici les principaux termes techniques qui ont été traduits de l'Anglais vers | macro | macro | - | | main | main | - | | memory management | gestion de mémoire | - | +| modern | récent | - | | module | module | - | | mutability | mutabilité | - | | mutable | mutable/modifiable | - | +| mutate | muter | - | | Note | Remarque | - | | numerical characters | chiffres | - | | operating system | système d'exploitation | - | @@ -88,6 +102,8 @@ Voici les principaux termes techniques qui ont été traduits de l'Anglais vers | Rustaceans | Rustacés | - | | section header | entête de section | - | | semantic version | version sémantique | - | +| scalar | scalaire | - | +| scope | portée | - | | script | script | - | | shadow | créer un fantôme | explication variable type inference | | Shadowing | La création de fantôme | variable type inference | @@ -99,6 +115,7 @@ Voici les principaux termes techniques qui ont été traduits de l'Anglais vers | standard | une convention/une norme | - | | standard library | bibliothèque standard | - | | statement | instruction/mot-clé | - | +| statically typed | statiquement typé | - | | strings | chaînes de caractères | - | | structs | structures | - | | submodules | sous-modules | - | @@ -108,12 +125,17 @@ Voici les principaux termes techniques qui ont été traduits de l'Anglais vers | terminal | terminal | - | | traits | traits | - | | Troubleshooting | Dépannage | - | +| type | type | - | +| type annotation | annotation de type | - | | type inference | déduction de type | - | +| two’s complement | complément à deux | - | +| two’s complement wrapping | rebouclage du complément à deux | - | | underlying operating system | élément du système d'exploitation | - | | underscore | trait de soulignement "_" | - | | unsafe | code non sécurisé | - | | unsigned | sans signe (toujours positif) | - | | user input | saisie utilisateur | - | +| variable | variable | - | | variants | variantes | - | | vectors | vecteurs | - | | version control system (VCS) | système de gestion de version (VCS) | - | From c6627696e0fc2676ddeeea865bd3ebe2039cfeab Mon Sep 17 00:00:00 2001 From: Jimskapt Date: Sat, 10 Aug 2019 15:12:35 +0200 Subject: [PATCH 036/117] :globe_with_meridians: Translating the other half of ch03-02 in French. --- FRENCH/src/SUMMARY.md | 2 +- FRENCH/src/ch03-02-data-types.md | 260 ++++++++++++++++++++++++++++++- FRENCH/src/translation-terms.md | 12 +- 3 files changed, 269 insertions(+), 5 deletions(-) diff --git a/FRENCH/src/SUMMARY.md b/FRENCH/src/SUMMARY.md index 8c4c0ef9f0..aa550f0099 100644 --- a/FRENCH/src/SUMMARY.md +++ b/FRENCH/src/SUMMARY.md @@ -5,4 +5,4 @@ - [Les types de données](ch03-02-data-types.md) - [Les fonctions](ch03-03-how-functions-work.md) - [Les commentaires](ch03-04-comments.md) - - [Les structure de contrôle](ch03-05-control-flow.md) + - [Les structures de contrôle](ch03-05-control-flow.md) diff --git a/FRENCH/src/ch03-02-data-types.md b/FRENCH/src/ch03-02-data-types.md index c57cf19032..43057c459c 100644 --- a/FRENCH/src/ch03-02-data-types.md +++ b/FRENCH/src/ch03-02-data-types.md @@ -352,16 +352,25 @@ type `f32` est un nombre à virgule flottante à simple précision, et le `f64` #### Numeric Operations --> +#### Les opérations numériques + +Rust offre les opérations mathématiques de base que vous auriez besoin pour tous +les types de nombres : addition, soustraction, multiplication, division et +reliquat. Le code suivant montre comment utiliser chacune d'elle avec une +instruction `let` : + +Nom du fichier : src/main.rs + +```rust +fn main() { + // addition + let somme = 5 + 10; + + // soustraction + let difference = 95.5 - 4.3; + + // multiplication + let produit = 4 * 30; + + // division + let quotient = 56.7 / 32.2; + + // reliquat + let reliquat = 43 % 5; +} +``` + +Chaque expression de ces instructions utilisent un opérateur mathématique et +calcule une valeur unique, qui est ensuite attribué à une variable. L'annexe B +présente une liste de tous les opérateurs que Rust fournit. + +#### Le type booléen + +Comme dans la plupart des langages de programmation, un type booléen a deux +valeurs possibles en Rust : `true` (vrai) et `false` (faux). Les booléens +prennent un octet en mémoire. Le type booléen est désigné en utilisant `bool`. +Par exemple : + +Nom du fichier : src/main.rs + +```rust +fn main() { + let t = true; + + let f: bool = false; // avec une annotation de type explicite +} +``` + +Les valeurs booléennes sont principalement utilisées par les structures +conditionnelles, comme l'expression `if`. Nous allons voir comme `if` fonctionne +avec Rust dans la section [“Les structures de contrôle”][control-flow]. + +#### Le type caractère + +Jusqu'à présent, nous avons utilisé uniquement des nombres, mais Rust peut aussi +travailler avec des lettres. Le type `char` *(comme character)* est le type de +caractère le plus rudimentaire, et le code suivant va vous montrer une façon de +l'utiliser. (A noter que les `char` sont écrits avec des guillemets simples, +contrairement aux chaînes, qui utilisent des guillemets doubles.) + +Nom du fichier : src/main.rs + +```rust +fn main() { + let c = 'z'; + let z = 'ℤ'; + let chat_aux_yeux_de_coeur = '😻'; +} +``` + +Le type `char` de Rust prend quatre octets en mémoire et représente une valeur +scalaire Unicode, ce qui veut dire que cela représente plus de caractères que +l'ASCII. Les lettres accentuées, les caractères chinois, japonais et coréens; +les emoji; les espaces de largeur nulle ont tous une valeur pour `char` avec +Rust. Les valeurs scalaires Unicode vont de `U+0000` à `U+D7FF` et de `U+E000` à +`U+10FFFF` inclus. Cependant, un “caractère” dans Rust n'est pas exactement le +même concept de Unicode, donc intuition humaine ce qu'est un “caractère” peut ne +pas correspondre exactement à ce qu'est un `char` avec Rust. Nous aborderons ce +sujet plus en détail au [chapitre 8](ch08-02-strings.html). + +### Les types composés + +Les *types composés* peuvent regrouper plusieurs valeurs dans un seul type. Rust +a deux types composés de base : les *tuples* et les tableaux *(arrays)*. + +#### Le type *tuple* + +Un *tuple* est fonctionnalité permettant de regrouper ensemble plusieurs valeurs +de type différent en un seul type composé. Les *tuples* ont une taille fixée : +à partir du moment où ils ont été déclarés, on ne peut pas y ajouter ou enlever +des valeurs. + +Nous créons un *tuple* en écrivant une liste séparée par des virgules entre des +parenthèses. Chaque emplacement dans le tuple a un type, et les types de chacune +des valeurs dans le tuple n'ont pas forcément besoin d'être les mêmes. +Nous avons ajouté des annotations de type dans cet exemple, mais c'est +optionnel : + +Nom du fichier : src/main.rs + ```rust fn main() { let tup: (i32, f64, u8) = (500, 6.4, 1); @@ -498,10 +599,17 @@ single compound element. To get the individual values out of a tuple, we can use pattern matching to destructure a tuple value, like this: --> +La variable `tup` est assigné à tout le *tuple*, car un tuple est considéré +comme étant un seul élément composé. Pour obtenir un élément précis de ce +*tuple*, nous pouvons utiliser un filtrage par motif *(pattern matching)* pour +déstructurer les valeurs d'un tuple, comme ceci : + +Nom du fichier : src/main.rs + +```rust +fn main() { + let tup = (500, 6.4, 1); + + let (x, y, z) = tup; + + println!("La valeur de y est : {}", y); +} +``` + +Le programme commence par créer un *tuple* et il l'assigne à la variable `tup`. +Il utilise ensuite un motif avec `let` pour prendre `tup` et le séparer dans +trois variables, `x`, `y`, et `z`. On appelle cela *destructurer*, car il divise +le *tuple* en trois parties. Puis finalement, le programme affiche la valeur de +`y`, qui est `6.4`. + +En plus de pouvoir déstructurer avec un filtrage par motif, nous pouvons accéder +directement à chaque élément du tuple en utilisant un point (`.`) suivi de +l'indice de la valeur que nous souhaitons obtenir. Par exemple : + +Nom du fichier : src/main.rs + +```rust +fn main() { + let x: (i32, f64, u8) = (500, 6.4, 1); + + let cinq_cents = x.0; + + let six_virgule_quatre = x.1; + + let un = x.2; +} +``` + +Ce programme crée un tuple, `x`, et ensuite crée une nouvelle variable pour +chaque élément en utilisant leur indice. Comme dans de nombreux langages de +programmation, le premier indice d'un tuple est 0. + +#### Le type tableau + +Un autre moyen d'avoir une collection de plusieurs valeurs est de le faire avec +un *tableau*. Contrairement au *tuple*, chaque élément du tableau doit être du +même type. Les tableaux de Rust diffèrent de ceux de certains autres langages +car les tableaux de Rust ont une taille fixe, comme les *tuple*. + +Avec Rust, les valeurs qui stockées dans un tableau sont écrites dans une +liste séparée par des virgules entre des crochets : + +Nom du fichier : src/main.rs + ```rust fn main() { let a = [1, 2, 3, 4, 5]; @@ -588,6 +746,16 @@ If you’re unsure whether to use an array or a vector, you should probably use vector. Chapter 8 discusses vectors in more detail. --> +Les tableaux sont utiles quand vous voulez que vos données soient stockées sur +la pile *(stack)* plutôt que sur le tas *(heap)* (nous expliquerons la pile et +le tas au chapitre 4) ou lorsque vous voulez vous assurer que vous avez toujours +un nombre fixe d'éléments. Cependant, un tableau n'est pas aussi flexible qu'un +type vecteur *(vector)*. Un vecteur est un type de collection de données +similaire qui est fourni par la bibliothèque standard qui *est* autorisé à +grandir ou rétrécir en taille. Si vous ne savez pas si vous devez utiliser un +tableau ou un vecteur, vous devriez probablement utiliser un vecteur. Le +chapitre 8 expliquera les vecteurs. + +Un exemple de cas où vous pourriez avoir recours à un tableau plutôt qu'à un +vecteur est un programme qui nécessite de savoir les noms des mois de l'année. +Il est très improbable qu'un tel programme ai besoin d'ajouter ou de supprimer +des mois, donc vous pouvez utiliser un tableau car vous savez qu'il contiendra +toujours 12 éléments : + +```rust +let mois = ["Janvier", "Février", "Mars", "Avril", "Mai", "Juin", "Juillet", + "Août", "Septembre", "Octobre", "Novembre", "Décembre"]; +``` + +Vous pouvez écrire le type d'un tableau en utilisant des crochets, et entre ces +crochets y ajouter le type de chaque élément, un point-virgule, et ensuite le +nombre d'éléments dans le tableau, comme ceci : + ```rust let a: [i32; 5] = [1, 2, 3, 4, 5]; ``` @@ -617,6 +800,9 @@ Here, `i32` is the type of each element. After the semicolon, the number `5` indicates the element contains five items. --> +Ici, `i32` est le type de chaque élément. Après le point-virgule, le nombre `5` +indique que le tableau contient cinq éléments. + +L'écriture d'un type de tableau de cette manière ressemble à une autre syntaxe +pour initialiser un tableau : si vous voulez créer un tableau qui contient la +même valeur pour chaque élément, vous pouvez préciser la valeur initiale, suivie +par un point-virgule, et ensuite la taille du tableau, le tout entre crochets, +comme ci-dessous : + ```rust let a = [3; 5]; ``` @@ -634,19 +826,31 @@ The array named `a` will contain `5` elements that will all be set to the value more concise way. --> +Le tableau `a` va contenir `5` éléments qui seront auront toutes la valeur +initiale `3`. C'est la même chose qu'écrire `let a = [3, 3, 3, 3, 3];` mais +de manière plus concise. + +##### Accéder aux éléments d'un tableau + +Un tableau est un simple bloc de mémoire alloué sur la pile. Vous pouvez accéder +aux éléments d'un tableau en utilisant l'indexation, comme ceci : + +Nom du fichier : src/main.rs + + + +```rust +fn main() { + let a = [1, 2, 3, 4, 5]; + + let premier = a[0]; + let second = a[1]; +} +``` +Dans cet exemple, la variable qui s'appelle `premier` aura la valeur `1`, car +c'est la valeur à l'indice `[0]` dans le tableau. La variable `second` +récupèrera la valeur `2` depuis l'indice `[1]` du tableau. + +##### Accès incorrect à un élément d'un tableau + +Que se passe-t-il quand vous essayez d'accéder à un élément d'un tableau qui se +trouve après la fin du tableau ? Imaginons que vous changiez l'exemple par le +code suivant, qui va compiler mais qui va quitter avec une erreur quand il sera +exécuté : + +Nom du fichier : src/main.rs + +```rust,ignore,panics +fn main() { + let a = [1, 2, 3, 4, 5]; + let indice = 10; + + let element = a[indice]; + + println!("La valeur de l'élément est : {}", element); +} +``` + +Exécuter ce code en utilisant `cargo run` va donner le résultat suivant : + ```text $ cargo run Compiling arrays v0.1.0 (file:///projects/arrays) @@ -711,6 +951,12 @@ than the array length. If the index is greater than or equal to the array length, Rust will panic. --> +La compilation n'a pas produit d'erreur, mais le programme a rencontré une +erreur *à l'exécution* et ne s'est pas terminé avec succès. Quand vous essayez +d'accéder à un élément en utilisant l'indexation, Rust va vérifier si l'indice +que vous avez demandé est plus petit que la taille du tableau. Si l'indice est +plus grand ou égal à la taille du tableau, Rust va *paniquer*. + +C'est un premier exemple pratique des principes de sécurité de Rust. Dans de +nombreux langages de bas-niveau, ce genre de vérification n'est pas effectuée, +et quand vous utilisez un indice incorrect, de la mémoire invalide peut être +récupérée. Rust vous protège de ce genre d'erreur en quittant immédiatement +l'exécution au lieu de continuer à accéder à ce qu'il y a en mémoire et +continuer son déroulement. Le chapitre 9 expliquera la gestion d'erreurs de +Rust. + [comparing-the-guess-to-the-secret-number]: ch02-00-guessing-game-tutorial.html#comparer-le-nombre-saisi-avec-le-nombre-secret - -[control-flow]: ch03-05-control-flow.html#control-flow -[strings]: ch08-02-strings.html#storing-utf-8-encoded-text-with-strings +[control-flow]: ch03-05-control-flow.html#les-structures-de-contrôle [wrapping]: ../std/num/struct.Wrapping.html diff --git a/FRENCH/src/translation-terms.md b/FRENCH/src/translation-terms.md index 7a97437c9a..1357a3acd6 100644 --- a/FRENCH/src/translation-terms.md +++ b/FRENCH/src/translation-terms.md @@ -8,6 +8,7 @@ Voici les principaux termes techniques qui ont été traduits de l'Anglais vers | allocated | alloué | - | | annotate | indiquer | - | | Application Programming Interface (API) | interface de programmation applicative (API) | - | +| array | tableau | - | | arguments | arguments/paramètres | - | | arms | branches | explication de match | | artifact | artéfact | - | @@ -23,10 +24,11 @@ Voici les principaux termes techniques qui ont été traduits de l'Anglais vers | code review | revue de code | - | | collection | collection | - | | commit | commit | - | -| compound | composés | - | +| compound | composé | - | | concept chapters | chapitres théoriques | - | | concurrency | concurrence | - | | concurrent | concurrent | - | +| conditionals | structures conditionnelles | - | | constant | constante | - | | control flow construct | structure de contrôle | - | | core of the error | message d'erreur | - | @@ -37,6 +39,7 @@ Voici les principaux termes techniques qui ont été traduits de l'Anglais vers | curly brackets | accolades | - | | data representation | modèle de données | - | | dependencies | dépendances | - | +| destructure | destructurer | - | | DevOps | DevOps | - | | enums | énumérations | - | | enumerations | énumérations | - | @@ -53,6 +56,7 @@ Voici les principaux termes techniques qui ont été traduits de l'Anglais vers | handle | référence | - | | hash | hachage | - | | hash maps | tables de hachage | - | +| heap | le tas | - | | Hello, world! | Hello, world! | - | | high-level | haut-niveau | - | | integer literal | entiers littéral | - | @@ -60,6 +64,8 @@ Voici les principaux termes techniques qui ont été traduits de l'Anglais vers | Integrated Development Environment (IDE) | Integrated Development Environment (IDE) | - | | IOT | internet des objets (IOT) | - | | immutable | immuable | - | +| index | indice | - | +| indexing | indexation | - | | iterators | itérateurs | - | | legacy code | code instable que le programme a hérité avec le temps | - | | libraries | bibliothèques | - | @@ -97,6 +103,7 @@ Voici les principaux termes techniques qui ont été traduits de l'Anglais vers | reference | réference | - | | registry | registre | - | | regression | régression | - | +| remainder | reliquat | - | | reproducible builds | compilation reproductive | - | | run | exécuter | pour les programmes | | Rustaceans | Rustacés | - | @@ -110,8 +117,10 @@ Voici les principaux termes techniques qui ont été traduits de l'Anglais vers | shell | terminal/invite de commande | - | | shorthand | abréviation | - | | sidebar | volet latéral | - | +| square brackets | crochets | - | | smart pointers | pointeurs intelligents | - | | snip | code inchangé masqué ici | inside Listings | +| stack | la pile | - | | standard | une convention/une norme | - | | standard library | bibliothèque standard | - | | statement | instruction/mot-clé | - | @@ -125,6 +134,7 @@ Voici les principaux termes techniques qui ont été traduits de l'Anglais vers | terminal | terminal | - | | traits | traits | - | | Troubleshooting | Dépannage | - | +| tuple | tuple | - | | type | type | - | | type annotation | annotation de type | - | | type inference | déduction de type | - | From f629b618342096dddfb90f91279d080688f000c5 Mon Sep 17 00:00:00 2001 From: Jimskapt Date: Sun, 11 Aug 2019 14:59:21 +0200 Subject: [PATCH 037/117] :globe_with_meridians: Translating ch03-03 in French. --- FRENCH/src/ch03-03-how-functions-work.md | 330 ++++++++++++++++++++++- FRENCH/src/translation-terms.md | 4 + 2 files changed, 333 insertions(+), 1 deletion(-) diff --git a/FRENCH/src/ch03-03-how-functions-work.md b/FRENCH/src/ch03-03-how-functions-work.md index cc76251085..efb5cfe8aa 100644 --- a/FRENCH/src/ch03-03-how-functions-work.md +++ b/FRENCH/src/ch03-03-how-functions-work.md @@ -2,6 +2,8 @@ ## Functions --> +## Les fonctions + +Les fonctions sont omniprésentes dans le code Rust. Vous avez déjà vu l'une des +fonctions les plus importantes du langage : la fonction `main`, qui est le point +d'entrée de beaucoup de programmes. Vous avez aussi vu le mot-clé `fn`, qui vous +permet de déclarer des nouvelles fonctions. + +Le code Rust utilise le *snake case* comme convention de style de nom des +fonctions et des variables. Avec le *snake case*, toutes les lettres sont en +minuscule et on utilise des tirets bas pour séparer les mots. Voici un programme +qui est un exemple de définition de fonction : + +Fichier : src/main.rs + +```rust +fn main() { + println!("Hello, world!"); + + une_autre_fonction(); +} + +fn une_autre_fonction() { + println!("Une autre fonction."); +} +``` + +La définition d'une fonction avec Rust commence par `fn` et a un jeu de +parenthèses après le nom de la fonction. Les accolades indiquent au compilateur +où le corps de la fonction commence et où il se termine. + +Nous pouvons appeler n'importe quelle fonction que nous avons déclaré en +utilisant son nom, suivi d'un jeu de parenthèses. Comme `une_autre_fonction` +est définie dans le programme, elle peut être appelée à l'intérieur de la +fonction `main`. Remarquez que nous avons déclaré `une_autre_fonction` *après* +la fonction `main` dans le code source; nous aurions aussi pu la déclarer avant. +Rust ne se soucie pas de l'endroit où vous déclarez vos fonctions, du moment +qu'elles sont bien définies quelque part. + +Créons un nouveau projet de binaire qui s'appelera *functions* afin d'en +apprendre plus sur les fonctions. Ajoutez l'exemple `une_autre_fonction` dans le +*src/main.rs* et exécutez-le. Vous devriez avoir ceci : + + + +```text +$ cargo run + Compiling functions v0.1.0 (file:///projects/functions) + Finished dev [unoptimized + debuginfo] target(s) in 0.28 secs + Running `target/debug/functions` +Hello, world! +Une autre fonction. +``` +Les lignes s'exécutent dans l'ordre dans lequel elles apparaissent dans la +fonction `main`. D'abord, le message `Hello, world!` est écrit, et ensuite +`une_autre_fonction` est appelée et son message est affiché. + +### Les paramètres de fonctions + +Les fonctions peuvent aussi être déclarées avec des *paramètres*, qui sont des +variables spéciales qui font partie de la signature de la fonction. Quand une +fonction a des paramètres, vous pouvez lui fournir des valeurs concrètes avec +ces paramètres. Techniquement, ces valeurs concrètes sont appelées des +*arguments*, mais dans une conversation courante, les personnes ont tendance à +confondre les termes *paramètres* et *arguments* pour désigner soit les +variables dans la définition d'une fonction, soit les valeurs concrètes passées +quand on utilise une fonction. + +La version réécrite de `une_autre_fonction` montre comment utiliser un paramètre +avec Rust : + +Fichier : src/main.rs + +```rust +fn main() { + une_autre_fonction(5); +} + +fn une_autre_fonction(x: i32) { + println!("La valeur de x est : {}", x); +} +``` + +En exécutant ce programme, vous devriez obtenir ceci : + +```text +$ cargo run + Compiling functions v0.1.0 (file:///projects/functions) + Finished dev [unoptimized + debuginfo] target(s) in 1.21 secs + Running `target/debug/functions` +La valeur de x est : 5 +``` + +La déclaration de `une_autre_fonction` a un paramètre appellé `x`. Le type de +`x` a été déclaré comme `i32`. Quand `5` est passé à `une_autre_fonction`, la +macro `println!` place `5` où la paire d'accolades `{}` a été placée dans le +texte de formatage. + +Dans la signature d'une fonction, vous *devez* déclarer le type de chaque +paramètre. C'est un choix délibéré de conception de Rust : demander l'annotation +de type dans la définition d'une fonction fait en sorte que le compilateur n'a +presque plus besoin que vous les utilisiez autre part pour qu'il comprenne ce +que vous voulez faire. + +Lorsque vous souhaitez qu'une fonction ait plusieurs paramètres, séparez les +paramètres avec des virgules, comme ceci : + +Fichier : src/main.rs + +```rust +fn main() { + une_autre_fonction(5, 6); +} + +fn une_autre_fonction(x: i32, y: i32) { + println!("La valeur de x est : {}", x); + println!("La valeur de y est : {}", y); +} +``` + +Cet exemple crée une fonction avec deux paramètres, chacun d'eux sont du type +`i32`. La fonction affiche ensuite les valeurs valeurs de ses deux paramètres. +Notez que les paramètres des fonctions n'ont pas besoin d'être du même type, +nous sommes dans cette situation uniquement pour les besoins de notre exemple. + +Essayons d'exécuter ce code. Remplacez le programme présent actuellement dans +votre fichier *src/main.rs* de votre projet *functions* par l'exemple précédent +et lancez-le en utilisant `cargo run` : + +```text +$ cargo run + Compiling functions v0.1.0 (file:///projects/functions) + Finished dev [unoptimized + debuginfo] target(s) in 0.31 secs + Running `target/debug/functions` +La valeur de x est : 5 +La valeur de y est : 6 +``` + +Comme nous avons appellé la fonction avec la valeur `5` pour `x` et `6` pour +`y`, deux lignes sont affichées avec ces valeurs. + +### Corps de fonction avec des déclarations et des expressions + +Les corps de fonctions sont constitués d'une série de déclarations qui se +terminent éventuellement par une expression. Jusqu'à présent, nous avons vu des +fonctions sans expression à la fin, mais vous avez déjà vu une expression faire +partie d'une déclaration. Comme Rust est un langage basé sur des expressions, +il est important de faire la distinction. Les autres langages ne font pas de +telles distinctions, donc penchons-nous sur ce que sont les déclarations et les +expressions et comment leurs différences influent sur le corps des fonctions. + +Nous avons déjà utilisé les déclarations et les expressions. Les *déclarations* +sont des instructions qui déclenchent certaines actions et qui ne retournent +aucune valeur. Les *expressions* sont évaluées pour retourner un résultat. +Voyons quelques exemples. + +Créez une variable et assignez-lui une valeur avec le mot-clé `let` qui fait une +déclaration. Dans l'encart 3-1, `let y = 6;` est une déclaration. + +Fichier : src/main.rs + ```rust fn main() { let y = 6; @@ -222,20 +383,32 @@ fn main() { Listing 3-1: A `main` function declaration containing one statement --> +Encart 3-1 : une fonction `main` qui contient une +déclaration + +La définition d'une fonction est aussi une déclaration; l'intégralité de +l'exemple précédent est une déclaration à elle toute seule. + +Une déclaration ne retourne pas de valeur. Ainsi, vous ne pouvez pas assigner +le résultat d'une déclaration `let` à une autre variable, comme le code suivant +essaye de le faire; car vous allez tomber sur une erreur : + +Fichier : src/main.rs + ```rust,ignore,does_not_compile fn main() { let x = (let y = 6); @@ -246,6 +419,9 @@ fn main() { When you run this program, the error you’ll get looks like this: --> +Quand vous exécutez ce programme, l'erreur que vous obtenez devrait ressembler à +ceci : + ```text $ cargo run Compiling functions v0.1.0 (file:///projects/functions) @@ -266,6 +442,12 @@ languages, you can write `x = y = 6` and have both `x` and `y` have the value `6`; that is not the case in Rust. --> +La déclaration `let y = 6` ne retourne pas de valeur, donc cela ne peut pas +devenir une valeur de `x`. Ceci est différent d'autres langages, comme le C ou +le Ruby, où les déclarations retournent la valeur de la déclaration. Dans ces +langages, vous pouvez écrire `x = y = 6` et avoir ainsi `x` et `y` qui ont +chacun la valeur `6`; cela n'est pas possible avec Rust. + +Les expressions sont évaluées et composent la plupart de ce que vous allez +écrire en Rust. Prenez une simple opération mathématique, comme `5 + 6`, qui est +une expression qui s'évalue à la valeur `11`. Les expressions peuvent faire +partie d'une déclaration : dans l'encart 3-1, le `6` dans la déclaration +`let y = 6;` est une expression qui s'évalue à la valeur `6`. Appeler une +fonction est aussi une expression. Appeler une macro est une expression. Le +bloc que nous utilisons pour créer une nouvelle portée, `{}`, est une +expression, par exemple : + +Fichier : src/main.rs + +```rust +fn main() { + let x = 5; + + let y = { + let x = 3; + x + 1 + }; + + println!("La valeur de y est : {}", y); +} +``` + + +L'expression suivante ... ```rust,ignore { @@ -304,7 +513,6 @@ This expression: x + 1 } ``` ---> +... est un bloc qui, dans ce cas, s'évalue à 4. Cette valeur est attribuée à `y` +dans le cadre de la déclaration avec `let`. Remarquez la ligne `x + 1` qui ne se +termine pas par un point-virgule à la fin, ce qui est différent de la plupart +des lignes que vous avez vu précédemment. Les expressions n'ont pas de +points-virgules de fin de ligne. Si vous ajoutez un point-virgule à la fin de +l'expression, vous la transformez en déclaration, qui ne va donc pas retourner +de valeur. Gardez ceci à l'esprit quand vous aborderez prochainement les valeurs +de retour des fonctions ainsi que les expressions. + +### Les fonctions qui retournent des valeurs + +Les fonctions peuvent retourner des valeurs au code qui les appellent. Nous +n'avons pas besoin de nommer les valeurs de retour, mais nous devons déclarer +leur type après une flèche (`->`). Dans Rust, la valeur de retour de la fonction +est liée à la valeur de l'expression finale dans le corps de la fonction. Vous +pouvez sortir prématurément d'une fonction en utilisant le mot-clé `return` et +en précisant une valeur, mais la plupart des fonctions vont retourner +implicitement la dernière expression. Voici un exemple d'une fonction qui +retourne une valeur : + +Fichier : src/main.rs + +```rust +fn cinq() -> i32 { + 5 +} + +fn main() { + let x = cinq(); + + println!("La valeur de x est : {}", x); +} +``` + +Il n'y a pas d'appel de fonction, de macro, même de déclaration `let` dans la +fonction `cinq` — uniquement le nombre `5` tout seul. C'est une fonction +parfaitement valide avec Rust. Remarquez que le type de retour de la fonction a +été précisé aussi, avec `-> i32`. Essayez d'exécuter ce code; le résultat +devrait ressembler à ceci : + +```text +$ cargo run + Compiling functions v0.1.0 (file:///projects/functions) + Finished dev [unoptimized + debuginfo] target(s) in 0.30 secs + Running `target/debug/functions` +La valeur de x est : 5 +``` + +Le `5` dans `cinq` est la valeur de retour de la fonction, ce qui explique le +type de retour de `i32`. Regardons cela plus en détail. Il y a deux éléments +importants : premièrement, la ligne `let x = cinq();` dit que nous utilisons +la valeur de retour de la fonction pour initialiser la variable. Comme la +fonction `cinq` retourne un `5`, cette ligne revient à faire ceci : + ```rust let x = 5; ``` @@ -382,14 +644,22 @@ return value, but the body of the function is a lonely `5` with no semicolon because it’s an expression whose value we want to return. --> +Ensuite, la fonction `cinq` n'a pas de paramètre et déclare le type de valeur +de retour, mais le corps de la fonction est un simple `5` sans point-virgule car +c'est une expression dont nous voulons retourner la valeur. + +Regardons un autre exemple : + +Fichier : src/main.rs + +```rust +fn main() { + let x = plus_un(5); + + println!("La valeur de x est : {}", x); +} + +fn plus_un(x: i32) -> i32 { + x + 1 +} +``` + +Exécuter ce code va afficher `La valeur de x est : 6`. Mais si nous ajoutons un +point-virgule à la fin de la ligne qui contient `x + 1`, ce qui la transforme +d'une expression à une déclaration, nous obtenons une erreur. + +Fichier : src/main.rs + +```rust,ignore,does_not_compile +fn main() { + let x = plus_un(5); + + println!("La valeur de x est : {}", x); +} + +fn plus_un(x: i32) -> i32 { + x + 1; +} +``` + +Compiler ce code va produire une erreur, comme ci-dessous : + + + +```text +error[E0308]: mismatched types + -- > src/main.rs:7:28 + | +7 | fn plus_un(x: i32) -> i32 { + | ___________________________^ +8 | | x + 1; + | | - help: consider removing this semicolon +9 | | } + | |_^ expected i32, found () + | + = note: expected type `i32` + found type `()` +``` + +Le message d'erreur principal, “mismatched types” *(types inadéquats)* donne le +coeur du problème de ce code. La définition de la fonction `plus_un` dit qu'elle +va retourner un `i32`, mais les déclarations ne retournent pas de valeur, ceci +est donc représenté par `()`, un *tuple* vide. Par conséquent, rien n'est +retourné, ce qui contredit la définition de la fonction et provoque une erreur. +Rust affiche un message qui peut aider à corriger ce problème : il suggère +d'enlever le point-virgule, ce qui va résoudre notre problème. + \ No newline at end of file diff --git a/FRENCH/src/translation-terms.md b/FRENCH/src/translation-terms.md index 7a97437c9a..a7ca0e91d4 100644 --- a/FRENCH/src/translation-terms.md +++ b/FRENCH/src/translation-terms.md @@ -84,6 +84,7 @@ Voici les principaux termes techniques qui ont été traduits de l'Anglais vers | package manager | système de gestion de paquets | - | | panic | panique(r) | - | | parallelism | parallélisme | - | +| parameter | paramètre | - | | PATH | PATH | - | | pattern | motif | - | | pattern-matching | filtrage par motif | - | @@ -110,11 +111,14 @@ Voici les principaux termes techniques qui ont été traduits de l'Anglais vers | shell | terminal/invite de commande | - | | shorthand | abréviation | - | | sidebar | volet latéral | - | +| signature | signature | d'une fonction | | smart pointers | pointeurs intelligents | - | +| snake case | snake case | - | | snip | code inchangé masqué ici | inside Listings | | standard | une convention/une norme | - | | standard library | bibliothèque standard | - | | statement | instruction/mot-clé | - | +| statement | déclaration | - | | statically typed | statiquement typé | - | | strings | chaînes de caractères | - | | structs | structures | - | From 6da2904f3c1ec5fe1555bd53d71c9615a4e5fc9d Mon Sep 17 00:00:00 2001 From: Jimskapt Date: Sun, 11 Aug 2019 17:27:20 +0200 Subject: [PATCH 038/117] Replacing 'nom du fichier' as requested in #41. --- FRENCH/src/ch03-01-variables-and-mutability.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/FRENCH/src/ch03-01-variables-and-mutability.md b/FRENCH/src/ch03-01-variables-and-mutability.md index c313aa9bc5..6c5d560311 100644 --- a/FRENCH/src/ch03-01-variables-and-mutability.md +++ b/FRENCH/src/ch03-01-variables-and-mutability.md @@ -43,7 +43,7 @@ remplacez son code par le code suivant qui ne compile pas pour le moment : Filename: src/main.rs --> -Nom du fichier : src/main.rs +Fichier : src/main.rs -Nom du fichier : src/main.rs +Fichier : src/main.rs -Nom du fichier : src/main.rs +Fichier : src/main.rs -Nom du fichier : src/main.rs +Fichier : src/main.rs -Nom du fichier : src/main.rs +Fichier : src/main.rs -Nom du fichier : src/main.rs +Fichier : src/main.rs -Nom du fichier : src/main.rs +Fichier : src/main.rs ```rust fn main() { @@ -608,7 +608,7 @@ déstructurer les valeurs d'un tuple, comme ceci : Filename: src/main.rs --> -Nom du fichier : src/main.rs +Fichier : src/main.rs -Nom du fichier : src/main.rs +Fichier : src/main.rs -Nom du fichier : src/main.rs +Fichier : src/main.rs ```rust fn main() { @@ -848,7 +848,7 @@ aux éléments d'un tableau en utilisant l'indexation, comme ceci : Filename: src/main.rs --> -Nom du fichier : src/main.rs +Fichier : src/main.rs -Nom du fichier : src/main.rs +Fichier : src/main.rs +## Les commentaires + +Tous les développeurs s'efforcent de rendre code facile à comprendre, mais +parfois il est nécessaire d'écrire plus d'explications. Dans ce cas, les +développeurs laissent des notes, appelées *commentaires*, dans leur code source +que le compilateur va ignorer mais que les personnes qui peuvent être utiles +pour les personnes qui lisent le code source. + +Voici un simple commentaire : + ```rust // hello, world ``` @@ -23,6 +33,10 @@ line. For comments that extend beyond a single line, you’ll need to include `//` on each line, like this: --> +Avec Rust, les commentaires commencent avec deux barres obliques et continue +jusqu'à la fin de la ligne. Pour des commentaires qui ont plus d'une seule +ligne, vous aurez besoin d'ajouter `//` sur chaque ligne, comme ceci : + +```rust +// Donc ici on fait quelque chose de compliqué, tellement long que nous avons +// besoin de plusieurs lignes de commentaires pour le faire ! Heureusement, +// ce commentaire va expliquer ce qui se passe. +``` + +Les commentaires peuvent aussi être aussi ajoutés à la fin de la ligne qui +contient du code : + +Fichier : src/main.rs + +```rust +fn main() { + let nombre_chanceux = 7; // Je me sent chanceux aujourd'hui +} +``` + +Mais parfois vous pourrez les voir utilisés de cette manière, avec le +commentaire sur une ligne séparée au-dessus du code qu'il annote : + +Fichier : src/main.rs + +```rust +fn main() { + // Je me sent chanceux aujourd'hui + let nombre_chanceux = 7; +} +``` + + +Rust a aussi un autre type de commentaire, les commentaires de documentation, +que nous allons aborder au chapitre 14. diff --git a/FRENCH/src/translation-terms.md b/FRENCH/src/translation-terms.md index 7a97437c9a..8216b4fc20 100644 --- a/FRENCH/src/translation-terms.md +++ b/FRENCH/src/translation-terms.md @@ -110,6 +110,7 @@ Voici les principaux termes techniques qui ont été traduits de l'Anglais vers | shell | terminal/invite de commande | - | | shorthand | abréviation | - | | sidebar | volet latéral | - | +| slashes | barre oblique | - | | smart pointers | pointeurs intelligents | - | | snip | code inchangé masqué ici | inside Listings | | standard | une convention/une norme | - | From fd1dc18dcf1abdb1e1cbae974af75a8b06e4154f Mon Sep 17 00:00:00 2001 From: Jimskapt Date: Mon, 12 Aug 2019 10:02:43 +0200 Subject: [PATCH 041/117] Replacing translation of 'shadowing' due to #38. --- .../src/ch03-01-variables-and-mutability.md | 24 +++++++++---------- 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/FRENCH/src/ch03-01-variables-and-mutability.md b/FRENCH/src/ch03-01-variables-and-mutability.md index 6c5d560311..dde8439400 100644 --- a/FRENCH/src/ch03-01-variables-and-mutability.md +++ b/FRENCH/src/ch03-01-variables-and-mutability.md @@ -362,7 +362,7 @@ doit être mise à jour à l'avenir. ### Shadowing --> -### *Shadowing* +### Le masquage du jeu de devinettes au chapitre 2, nous pouvons déclarer de nouvelles variables -avec le même nom qu'une variable précédente, et que la nouvelle variable sera un -fantôme de la première. Les Rustacés disent que la première variable est *un -fantôme* de la seconde, ce qui signifie que la valeur de la seconde variable -sera ce que nous obtiendrons lorsque nous utiliserons cette variable. Nous -pouvons créer un fantôme d'une variable en utilisant le même nom de variable et -en réutilisant le mot-clé `let` comme ci-dessous : +avec le même nom qu'une variable précédente, et que la nouvelle variable +masquera la première. Les Rustacés disent que la première variable est *masquée* +par la seconde, ce qui signifie que la valeur de la seconde variable sera ce que +nous obtiendrons lorsque nous utiliserons cette variable. Nous pouvons créer un +masque d'une variable en utilisant le même nom de variable et en réutilisant le +mot-clé `let` comme ci-dessous : -Au début, ce programme lie `x` à la valeur `5`. Puis il crée un fantôme de `x` +Au début, ce programme lie `x` à la valeur `5`. Puis il crée un masque de `x` en répétant `let x =`, ce qui récupère la valeur originale et lui ajoute `1` : la valeur de `x` est désormais `6`. La troisième instruction `let` crée un autre -fantôme de `x`, en récupérant la précédente valeur et en la multipliant par `2` +masque de `x`, en récupérant la précédente valeur et en la multipliant par `2` pour donner à `x` la valeur finale de `12`. Lorsque nous exécutons ce programme, nous obtenons ceci : @@ -458,7 +458,7 @@ on a value but have the variable be immutable after those transformations have been completed. --> -La création de fantôme est différente que de marquer une variable comme `mut`, +La création d'un masque est différent que de marquer une variable comme `mut`, car à moins d'utiliser une nouvelle fois le mot-clé `let`, nous obtiendrons une erreur de compilation si nous essayons de réassigner cette variable oar accident. Nous pouvons effectuer quelques transformations sur une valeur avec @@ -474,7 +474,7 @@ inputting space characters, but we really want to store that input as a number: --> Comme nous créons une nouvelle variable lorsque nous utilisons le mot-clé `let` -une nouvelle fois, l'autre différence entre le `mut` et la création de fantôme +une nouvelle fois, l'autre différence entre le `mut` et la création d'un masque est que cela nous permet de changer le type de la valeur, mais en réutilisant le même nom. Par exemple, imaginons un programme qui affiche le nombre d'espaces que saisit l'utilisateur, mais que nous voulons vraiment enregistrer cela sous @@ -504,7 +504,7 @@ try to use `mut` for this, as shown here, we’ll get a compile-time error: Cette solution est autorisée car la première variable `espaces` est du type chaîne de caractères *(string)*, alors que la seconde variable `espaces`, qui est une toute nouvelle variable qui se trouve avoir le même nom que la première, -est du type nombre. L'utilisation de fantômes nous évite ainsi d'avoir à trouver +est du type nombre. L'utilisation du masquage nous évite ainsi d'avoir à trouver des noms différents, comme `espaces_str` et `espaces_num` ; nous pouvons plutôt simplement utiliser le nom de `espaces`. Cependant, si nous essayons d'utiliser `mut` pour faire ceci, comme ci-dessous, nous avons une erreur de compilation : From ed3ba8743469ca8c49a74006f8d39a827132073e Mon Sep 17 00:00:00 2001 From: William Droz Date: Mon, 12 Aug 2019 16:08:16 +0200 Subject: [PATCH 042/117] add does_not_compile for a snippet The snippet in the section "The `?` Operator Can Only Be Used in Functions That Return `Result`" doesn't compile (as expected) thus I added the "does_not_compile" keyword. --- src/ch09-02-recoverable-errors-with-result.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ch09-02-recoverable-errors-with-result.md b/src/ch09-02-recoverable-errors-with-result.md index 85c4192836..c6529b2bcb 100644 --- a/src/ch09-02-recoverable-errors-with-result.md +++ b/src/ch09-02-recoverable-errors-with-result.md @@ -481,7 +481,7 @@ must be a `Result` to be compatible with this `return`. Let’s look at what happens if we use the `?` operator in the `main` function, which you’ll recall has a return type of `()`: -```rust,ignore +```rust,ignore,does_not_compile use std::fs::File; fn main() { From 133da0c820b066525c9f8c1ef4ef65720c49f898 Mon Sep 17 00:00:00 2001 From: Jimskapt Date: Tue, 13 Aug 2019 13:54:25 +0200 Subject: [PATCH 043/117] :globe_with_meridians: Translating ch03-05 in French. --- FRENCH/src/SUMMARY.md | 2 +- FRENCH/src/ch03-05-control-flow.md | 525 +++++++++++++++++++++++++++++ FRENCH/src/translation-terms.md | 5 +- 3 files changed, 530 insertions(+), 2 deletions(-) diff --git a/FRENCH/src/SUMMARY.md b/FRENCH/src/SUMMARY.md index 8c4c0ef9f0..aa550f0099 100644 --- a/FRENCH/src/SUMMARY.md +++ b/FRENCH/src/SUMMARY.md @@ -5,4 +5,4 @@ - [Les types de données](ch03-02-data-types.md) - [Les fonctions](ch03-03-how-functions-work.md) - [Les commentaires](ch03-04-comments.md) - - [Les structure de contrôle](ch03-05-control-flow.md) + - [Les structures de contrôle](ch03-05-control-flow.md) diff --git a/FRENCH/src/ch03-05-control-flow.md b/FRENCH/src/ch03-05-control-flow.md index 765278c4e3..e89bdbd361 100644 --- a/FRENCH/src/ch03-05-control-flow.md +++ b/FRENCH/src/ch03-05-control-flow.md @@ -2,6 +2,8 @@ ## Control Flow --> +## Les structures de contrôle + +Choisir d'exécuter ou non du code en fonction du résultat d'une condition et +choisir d'exécuter du code de façon répétée en fonction du résultat d'une autre +condition sont des instructions élémentaires dans de la plupart des langages de +programmation. Les structures de contrôle les plus courantes sont les +expressions `if` et les boucles. + +### Les expressions `if` + +Une expression `if` vous permet de diviser votre code en fonction de conditions. +Vous précisez une condition et vous choisissez ensuite : "si cette condition est +remplie, alors exécuter ce bloc de code. Si votre condition n'est pas remplie, +ne pas exécuter ce bloc de code." + +Créez un nouveau projet appelé *branches* dans votre dossier *projects* pour +découvrir les expressions `if`. Dans le fichier *src/main.rs*, écrivez ceci : + +Fichier : src/main.rs + +```rust +fn main() { + let nombre = 3; + + if nombre < 5 { + println!("La condition est vérifiée"); + } else { + println!("La condition n'est pas vérifiée"); + } +} +``` + +Une expression `if` commence par le mot-clé `if`, et est suivi d'une condition. +Dans notre cas, la condition vérifie si oui ou non la variable `nombre` a une +valeur inférieure à 5. Le bloc de code que nous voulons exécuter si la condition +est vérifiée est placé immédiatement après la condition entre des accolades. +Les blocs de code associés à une condition dans une expression `if` sont parfois +appelés des *branches*, exactement comme les branches dans les expressions +`match` que nous avons vu dans la section [“Comparer le nombre saisi avec le +nombre secret”][comparing-the-guess-to-the-secret-number] du +chapitre 2. + +Eventuellement, vous pouvez aussi ajouter une expression `else`, ce que nous +avons fait ici, pour préciser un bloc alternatif de code qui sera exécuté dans +le cas où le résultat de la condition est faux (elle n'est pas vérifiée). Si +vous ne renseignez pas d'expression `else` et que la condition n'est pas +vérifiée, le programme va simplement sauter le bloc de `if` et passer au +prochain morceau de code. + +Essayez d'exécuter ce code, vous verrez ceci : + +```text +$ cargo run + Compiling branches v0.1.0 (file:///projects/branches) + Finished dev [unoptimized + debuginfo] target(s) in 0.31 secs + Running `target/debug/branches` +La condition est vérifiée +``` + +Essayons de changer la valeur de `nombre` pour une valeur qui rend la condition +non vérifiée pour voir ce qui se passe : + +```rust,ignore +let nombre = 7; +``` + +Exécutez à nouveau le programme, et regardez le résultat : + +```text +$ cargo run + Compiling branches v0.1.0 (file:///projects/branches) + Finished dev [unoptimized + debuginfo] target(s) in 0.31 secs + Running `target/debug/branches` +La condition n'est pas vérifiée +``` + +Il est aussi intéressant de noter que la condition dans ce code *doit* être un +`bool`. Si la condition n'est pas un `bool`, nous aurons une erreur. Par +exemple, essayez d'exécuter le code suivant : + +Fichier : src/main.rs + +```rust,ignore,does_not_compile +fn main() { + let nombre = 3; + + if nombre { + println!("Le nombre était trois"); + } +} +``` + +La condition `if` vaut `3` cette fois, et Rust lève une erreur : + + + +```text +error[E0308]: mismatched types + -- > src/main.rs:4:8 + | +4 | if nombre { + | ^^^^^^ expected bool, found integral variable + | + = note: expected type `bool` + found type `{integer}` +``` +Cette erreur explique que Rust attendait un `bool` mais a obtenu un entier +*(integer)*. Contrairement à des langages comme le Ruby et le Javascript, Rust +ne va pas essayer de convertir automatiquement les types non booléens en +booléen. Vous devez être précis et toujours fournir un booléen à la condition +d'un `if`. Si nous voulons que le bloc de code du `if` soit exécuté quand le +nombre est différent de `0`, par exemple, nous pouvons changer l'expression `if` +par la suivante : + +Fichier: src/main.rs + +```rust +fn main() { + let nombre = 3; + + if nombre != 0 { + println!("Le nombre valait autre chose que zéro"); + } +} +``` + +Exécuter ce code va bien afficher `Le nombre valait autre chose que zéro`. + +#### Gérer plusieurs conditions avec `else if` + +Vous pouvez utiliser plusieurs conditions en combinant `if` et `else` dans une +expression `else if`. Par exemple : + +Fichier : src/main.rs + +```rust +fn main() { + let nombre = 6; + + if nombre % 4 == 0 { + println!("Le nombre est divisible par 4"); + } else if nombre % 3 == 0 { + println!("Le nombre est divisible par 3"); + } else if nombre % 2 == 0 { + println!("Le nombre est divisible par 2"); + } else { + println!("Le nombre n'est pas divisible par 4, 3, ou 2"); + } +} +``` + +Ce programme peut choisir entre quatre chemins différents. Après l'avoir +exécuté, vous devriez voir le résultat suivant : + +```text +$ cargo run + Compiling branches v0.1.0 (file:///projects/branches) + Finished dev [unoptimized + debuginfo] target(s) in 0.31 secs + Running `target/debug/branches` +Le nombre est divisible par 3 +``` + +Quand ce programme s'exécute, il vérifie chaque expression `if` à tour de rôle +et exécute le premier bloc dont la condition est vérifiée. Notez que même si 6 +est divisible par 2, nous ne voyons pas le message `Le nombre est divisible par +2` du bloc `else`. C'est parce que Rust n'exécute que le bloc de la première +condition vérifiée, et dès lorsqu'il en a trouvé une, il ne va pas chercher à +vérifier les suivantes. + +Utiliser trop d'expressions `else if` peut encombrer votre code, donc si vous +en avez plus d'une, vous devriez envisager de remanier votre code. Le chapitre 6 +présente une construction puissante appelée `match` pour de tels cas. + +#### Utiliser `if` dans une déclaration `let` + +Comme `if` est une expression, nous pouvons l'utiliser à droite d'une +déclaration `let`, comme dans l'encart 3-2. + +Fichier : src/main.rs + +```rust +fn main() { + let condition = true; + let nombre = if condition { + 5 + } else { + 6 + }; + + println!("La valeur du nombre est : {}", nombre); +} +``` + +Encart 3-2 : assigner le résultat d'une expression `if` à +une variable + +La variable `nombre` va avoir la valeur du résultat de l'expression `if`. +Exécutez ce code pour découvrir ce qui va se passer : + +```text +$ cargo run + Compiling branches v0.1.0 (file:///projects/branches) + Finished dev [unoptimized + debuginfo] target(s) in 0.30 secs + Running `target/debug/branches` +La valeur du nombre est : 5 +``` + +Souvenez-vous que les blocs de code s'exécutent jusqu'à la dernière expression +qu'ils contiennent, et que les nombres tout seuls sont aussi des expressions. +Dans notre cas, la valeur de toute l'expression `if` dépend de quel bloc de code +elle va exécuter. Cela veut dire que chaque valeur qui peut être le résultat de +chaque branche du `if` doivent être du même type; dans l'encart 3-2, les +résultats de la branche de `if` et de `else` sont chacun des entier `i32`. Si +les types ne sont pas accordés, comme dans l'exemple suivant, nous allons +obtenir une erreur : + +Fichier : src/main.rs + +```rust,ignore,does_not_compile +fn main() { + let condition = true; + + let nombre = if condition { + 5 + } else { + "six" + }; + + println!("La valeur du nombre est : {}", nombre); +} +``` + +Lorsque nous essayons de compiler ce code, nous obtenons une erreur. Les +branches `if` et `else` ont des types de valeurs qui ne sont pas compatibles, et +Rust indique exactement où trouver le problème dans le programme : + + + +```text +error[E0308]: if and else have incompatible types + -- > src/main.rs:4:18 + | +4 | let nombre = if condition { + | __________________^ +5 | | 5 +6 | | } else { +7 | | "six" +8 | | }; + | |_____^ expected integral variable, found &str + | + = note: expected type `{integer}` + found type `&str` +``` +L'expression dans le bloc `if` donne un entier, et l'expession dans le bloc +`else` donne une chaîne de caractères. Ceci ne fonctionne pas car les variables +doivent avoir un seul type. Rust a besoin de savoir de quel type est la variable +`nombre` au moment de la compilation, sans exception, afin de vérifier au moment +de la compilation que son type est valable n'importe où nous utilisons `nombre`. +Rust ne serait pas capable de faire cela si le type de `nombre` était déterminé +uniquement à l'exécution; car le compilateur deviendrait plus complexe et nous +donnerait moins de garanties sur le code s'il devait prendre en compte tous les +types hypothétiques pour une variable. + +### Les répétitions avec les boucles + +Il est parfois utile d'exécuter un bloc de code plus d'une seule fois. Dans ce +but, Rust propose plusieurs types de *boucles*. Une boucle parcourt le code à +l'intérieur du corps de la boucle jusqu'à la fin, et retourne immédiatement au +début. Pour tester les boucles, créons un nouveau projet appelé *loops*. + +Rust a trois types de boucles : `loop`, `while`, et `for`. Essayons chacune +d'elles. + +#### Répéter du code avec `loop` + +Le mot-clé `loop` demande à Rust d'exécuter un bloc de code encore et encore +jusqu'à l'infini ou jusqu'à ce que vous lui demandiez explicitement de +s'arrêter. + +Par exemple, changez le fichier *src/main.rs* dans votre dossier *loops* comme +ceci : + +Fichier : src/main.rs + +```rust,ignore +fn main() { + loop { + println!("A nouveau !"); + } +} +``` + +Quand nous exécutons ce programme, nous voyons `A nouveau !` écrit encore et +encore, continuellement jusqu'à ce qu'on arrête le programme manuellement. La +plupart des terminaux utilisent un raccourci clavier, +ctrl-c, pour arrêter un programme qui est bloqué dans une boucle infinie. +Essayons cela : + +```text +$ cargo run + Compiling loops v0.1.0 (file:///projects/loops) + Finished dev [unoptimized + debuginfo] target(s) in 0.29 secs + Running `target/debug/loops` +A nouveau ! +A nouveau ! +A nouveau ! +A nouveau ! +^CA nouveau !! +``` + +Le symbole `^C` représente le moment où vous avez appuyé sur +ctrl-c. Vous devriez voir ou non le texte +`A nouveau !` après le `^C`, en fonction de où la boucle en était dans votre +code quand elle a reçu le signal d'arrêt. + +Heureusement, Rust fournit un autre moyen, plus fiable, de sortir d'une boucle. +Vous pouvez ajouter le mot-clé `break` à l'intérieur de la boucle pour demander +au programme d'arrêter la boucle. Souvenez-vous que nous avions fait ceci dans +le jeu de devinettes, dans la section +[“Arrêter le programme après avoir gagné”][quitting-after-a-correct-guess] +du chapitre 2 afin de quitter le programme quand l'utilisateur gagne le jeu en +devinant le bon nombre. + +#### Retourner des valeurs d'une boucle + +L'une des utilisations d'un `loop` est de réessayer une opération qui peut +échouer, comme vérifier si un processus a terminé son travail. Cependant, vous +aurez peut-être besoin de passer le résultat de l'opération au reste de votre +code. Pour faire ainsi, vous pouvez ajouter la valeur que vous voulez retourner +après l'expression `break` que vous utilisez pour stopper la boucle; cette +valeur sera retournée de la boucle pour que vous puissiez l'utiliser, comme +ci-dessous : + +```rust +fn main() { + let mut compteur = 0; + + let resultat = loop { + compteur += 1; + + if compteur == 10 { + break compteur * 2; + } + }; + + println!("Le résultat est {}", resultat); +} +``` + +Avant la boucle, nous déclarons une variable avec le nom `compteur` et nous +l'initialisons à `0`. Ensuite, nous déclarons une variable `resultat` pour +stocker la valeur retournée de la boucle. A chaque itération de la boucle, nous +ajoutons `1` à la variable `compteur`, et ensuite nous vérifions si le compteur +est égal à `10`. Lorsque c'est le cas, nous utilisons le mot-clé `break` avec la +valeur `compteur * 2`. Après la boucle, nous utilisons un point-virgule pour +terminer la déclaration qui assigne la valeur à `resultat`. Enfin, nous +affichons la valeur de `resultat`, qui est 20 dans ce cas-ci. + +#### Les boucles conditionnelles avec `while` + +Il est parfois utile pour un programme d'évaluer une condition dans une boucle. +Quand la condition est vraie, la boucle tourne. Quand la condition arrête +d'être vraie, le programme utilise `break`, ce qui arrête la boucle. Ce type de +boucle peut être implémenté en combinant `loop`, `if`, `else` et `break`; vous +pouvez essayer de le faire, si vous voulez. + +Cependant, cette utilisation est si fréquente que Rust a une instruction pour +cela, intégrée dans le langage, qui s'appelle une boucle `while`. L'encart 3-3 +utilise `while` : le programme va boucler trois fois, en décrémentant à chaque +fois, et ensuite, après la boucle, il va afficher un message et se fermer. + +Fichier : src/main.rs + +```rust +fn main() { + let mut nombre = 3; + + while nombre != 0 { + println!("{} !", nombre); + + nombre -= 1; + } + + println!("DECOLLAGE !!!"); +} +``` + +Encart 3-3: utiliser une boucle `while` pour exécuter du +code tant qu'une condition est vraie + +Cette instruction élimine beaucoup d'imbrications qui seraient nécessaires si +vous utilisiez `loop`, `if`, `else` et `break`, et c'est aussi plus clair. Tant +que la condition est vraie, le code est exécuté; sinon, il quitte la boucle. + +#### Boucler dans une collection avec `for` + +Vous pouvez utiliser l'instruction `while` pour itérer créer une boucle sur les +éléments d'une collection, comme les tableaux. Par exemple, analysons l'encart +3-4. + +Fichier : src/main.rs + +```rust +fn main() { + let a = [10, 20, 30, 40, 50]; + let mut indice = 0; + + while indice < 5 { + println!("La valeur est : {}", a[indice]); + + indice += 1; + } +} +``` + +Encart 3-4 : boucle pour chaque élément d'une collection en +utilisant une boucle `while` + +Ici, le code va compter à partir du nombre d'éléments dans le tableau. Il +commence à l'indice `0`, et ensuite boucle jusqu'à ce qu'il atteigne l'indice +final du tableau (ce qui correspond au moment où la condition `index < 5` n'est +plus vraie). Exécuter ce code va afficher chaque élément du tableau : + +```text +$ cargo run + Compiling loops v0.1.0 (file:///projects/loops) + Finished dev [unoptimized + debuginfo] target(s) in 0.32 secs + Running `target/debug/loops` +La valeur est : 10 +La valeur est : 20 +La valeur est : 30 +La valeur est : 40 +La valeur est : 50 +``` + +Toutes les cinq valeurs du tableau s'affichent dans le terminal, comme attendu. +Même si `indice` va avoir la valeur `5` à un moment, la boucle arrêtera de +s'exécuter avant d'essayer de récupérer une sixième valeur du tableau. + +Mais cette pratique pousse à l'erreur; nous pourrions faire paniquer le +programme si l'indice est incorrect. Aussi, c'est lent, car le compilateur +ajoute du code d'exécution pour effectuer des vérifications sur chaque élément à +chaque itération de la boucle. + +Pour une alternative plus concise, vous pouvez utiliser une boucle `for` et +exécuter du code pour chaque élément dans une collection. Une boucle `for` +s'utilise comme dans le code de l'encart 3-5. + +Fichier : src/main.rs + +```rust +fn main() { + let a = [10, 20, 30, 40, 50]; + + for element in a.iter() { + println!("La valeur est : {}", element); + } +} +``` + +Encart 3-5 : itérer pour chaque élément d'une collection +en utilisant une boucle `for` + +Lorsque nous exécutons ce code, nous obtenons les mêmes messages que dans +l'encart 3-4. Mais ce qui est plus important, c'est que nous avons amélioré la +sécurité de notre code et éliminé le risque de bogues qui pourraient résulter +de la sortie de la limite du tableau, ou ne pas aller jusqu'au bout du tableau +et rater quelques éléments. + +Par exemple, dans le code de l'encart 3-4, si vous enleviez un élément du +tableau `a` mais que vous oubliez de mettre à jour la condition tel que +`while indice < 4`, le code va paniquer. En utilisant la boucle `for`, vous +n'aurez pas à vous rappeler de changer le code si vous changez le nombre de +valeurs dans le tableau. + +La sécurité et la concision de la boucle `for` en fait l'instruction de boucle +la plus utilisée avec Rust. Même dans des situations dans lesquelles vous +voudriez exécuter du code plusieurs fois, comme l'exemple du décompte qui +utilisait une boucle `while` dans l'encart 3-3, la plupart des Rustacés +utiliseraient une boucle `for`. Il faut pour cela utiliser un `Range`, qui est +un type fourni par la bibliothèque standard qui génère tous les nombres dans +l'ordre en commençant par un nombre et en finissant par un autre nombre. + +Voici ce que le décompte aurait donné en utilisant une boucle `for` et une autre +méthode que nous n'avons pas encore vu, `rev`, qui inverse le sens des données : + +Fichier : src/main.rs + +```rust +fn main() { + for nombre in (1..4).rev() { + println!("{} !", nombre); + } + println!("DECOLLAGE !!!"); +} +``` + +Ce code est un peu plus sympa, non ? + +## Résumé + +Vous y êtes arrivé ! C'était un chapitre important : vous avez appris les +variables, les types scalaires et composés, les fonctions, les commentaires, les +expressions `if`, et les boucles ! Si vous voulez pratiquer un peu les concepts +abordés dans ce chapitre, voici quelques programmes que vous pouvez essayer de +créer : + +* Convertir des températures entre les Fahrenheit et les Celsius. +* Générer le *n*-ième nombre de Fibonacci. +* Ecrire les paroles de la chanson de Noël, “Les Douze Jours de Noël”, en + profitant de l'aspect répétitif de la chanson. + +Quand vous serez prêt à aller plus loin, nous allons aborder une notion de Rust +qui n'existe *pas* dans les autres langages de programmation : la possession +*(ownership)*. + + + +[comparing-the-guess-to-the-secret-number]: +ch02-00-guessing-game-tutorial.html#comparer-le-nombre-saisi-avec-le-nombre-secret +[quitting-after-a-correct-guess]: +ch02-00-guessing-game-tutorial.html#arrêter-le-programme-après-avoir-gagné diff --git a/FRENCH/src/translation-terms.md b/FRENCH/src/translation-terms.md index 7a97437c9a..fa2b2ebeba 100644 --- a/FRENCH/src/translation-terms.md +++ b/FRENCH/src/translation-terms.md @@ -9,7 +9,7 @@ Voici les principaux termes techniques qui ont été traduits de l'Anglais vers | annotate | indiquer | - | | Application Programming Interface (API) | interface de programmation applicative (API) | - | | arguments | arguments/paramètres | - | -| arms | branches | explication de match | +| arm | branche | explication de match et de if | | artifact | artéfact | - | | associated functions | fonctions associées | - | | binary crate | crate binaire | - | @@ -28,6 +28,7 @@ Voici les principaux termes techniques qui ont été traduits de l'Anglais vers | concurrency | concurrence | - | | concurrent | concurrent | - | | constant | constante | - | +| construct | instruction | - | | control flow construct | structure de contrôle | - | | core of the error | message d'erreur | - | | corruption | être corrompu | - | @@ -58,10 +59,12 @@ Voici les principaux termes techniques qui ont été traduits de l'Anglais vers | integer literal | entiers littéral | - | | integer overflow | dépassement d'entier | - | | Integrated Development Environment (IDE) | Integrated Development Environment (IDE) | - | +| interrupt signal | signal d'arrêt | - | | IOT | internet des objets (IOT) | - | | immutable | immuable | - | | iterators | itérateurs | - | | legacy code | code instable que le programme a hérité avec le temps | - | +| loop | boucle | - | | libraries | bibliothèques | - | | library crate | crate de bibliothèque | - | | lifetimes | durées de vie | - | From aafa6e2a4ed10117152ec35bc64661fa16977540 Mon Sep 17 00:00:00 2001 From: Jimskapt Date: Thu, 15 Aug 2019 11:16:49 +0200 Subject: [PATCH 044/117] :globe_with_meridians: Translating ch04-00 in French. --- FRENCH/src/SUMMARY.md | 2 ++ FRENCH/src/ch04-00-understanding-ownership.md | 20 +++++++++++++++++++ FRENCH/src/translation-terms.md | 2 ++ 3 files changed, 24 insertions(+) create mode 100644 FRENCH/src/ch04-00-understanding-ownership.md diff --git a/FRENCH/src/SUMMARY.md b/FRENCH/src/SUMMARY.md index f523a5e7d3..a312e04a8d 100644 --- a/FRENCH/src/SUMMARY.md +++ b/FRENCH/src/SUMMARY.md @@ -8,3 +8,5 @@ - [Installation](ch01-01-installation.md) - [Hello, world!](ch01-02-hello-world.md) - [Hello, Cargo!](ch01-03-hello-cargo.md) + +- [Comprendre la possession](ch04-00-understanding-ownership.md) diff --git a/FRENCH/src/ch04-00-understanding-ownership.md b/FRENCH/src/ch04-00-understanding-ownership.md new file mode 100644 index 0000000000..4f78562a81 --- /dev/null +++ b/FRENCH/src/ch04-00-understanding-ownership.md @@ -0,0 +1,20 @@ + + +# Comprendre la possession + + + +La possession est la fonctionnalité la remarquable de Rust, et elle permet à +Rust de garantir la sécurité de la mémoire sans avoir besoin d'un +ramasse-miettes. Par conséquent, il est important de comprendre comment la +possession fonctionne avec Rust. Dans ce chapitre, nous aborderons la +possession, ainsi que d'autres fonctionnalités associées : l'emprunt, les +slices, et comprendre comment Rust conserve les données dans la mémoire. diff --git a/FRENCH/src/translation-terms.md b/FRENCH/src/translation-terms.md index d3146acecf..8f827f1d60 100644 --- a/FRENCH/src/translation-terms.md +++ b/FRENCH/src/translation-terms.md @@ -49,6 +49,7 @@ français. | field | champ | d'une structure | | flag | drapeau | pour les programmes en ligne de commande | | function | fonction | - | +| garbage collector | ramasse-miettes | - | | generics | génériques / généricité | - | | guessing game | jeu de devinettes | - | | handle | référence | - | @@ -113,6 +114,7 @@ français. | sidebar | barre latérale | - | | signature | signature | d'une fonction | | signed | signé | - | +| slice | slice | - | | smart pointer | pointeur intelligent | - | | snip | code inchangé masqué ici | dans un encart | | space | espace | ce mot est féminin quand on parle du caractère typographique | From bc42128f405e7ca0dc1a0c62c56214883623f34f Mon Sep 17 00:00:00 2001 From: Jimskapt Date: Fri, 16 Aug 2019 10:22:45 +0200 Subject: [PATCH 045/117] :twisted_rightwards_arrows: Merging translation of ch04-01 by @Jimskapt From https://github.com/quadrifoglio/rust-book-fr/blob/fr-ch04/second-edition/src/ch04-01-what-is-ownership.md --- FRENCH/src/ch04-01-what-is-ownership.md | 1278 +++++++++++++++++++++++ FRENCH/src/img/trpl04-01.svg | 68 ++ FRENCH/src/img/trpl04-02.svg | 95 ++ FRENCH/src/img/trpl04-03.svg | 123 +++ FRENCH/src/img/trpl04-04.svg | 96 ++ 5 files changed, 1660 insertions(+) create mode 100644 FRENCH/src/ch04-01-what-is-ownership.md create mode 100644 FRENCH/src/img/trpl04-01.svg create mode 100644 FRENCH/src/img/trpl04-02.svg create mode 100644 FRENCH/src/img/trpl04-03.svg create mode 100644 FRENCH/src/img/trpl04-04.svg diff --git a/FRENCH/src/ch04-01-what-is-ownership.md b/FRENCH/src/ch04-01-what-is-ownership.md new file mode 100644 index 0000000000..f50fc0752e --- /dev/null +++ b/FRENCH/src/ch04-01-what-is-ownership.md @@ -0,0 +1,1278 @@ + + +## Qu'est-ce que l'appropriation ? + + + +La fonctionnalité centrale de Rust est *l'appropriation*. Bien que cette +fonctionnalité soit simple à expliquer, elle a de profondes conséquences sur le +reste du langage. + + + +Tous les programmes doivent gérer la façon dont ils utilisent la mémoire +(vive, RAM) de l'ordinateur lorsqu'ils s'exécutent. Certains langages ont un +ramasse-miettes qui scrute constamment la mémoire qui n'est plus utilisée par +le programme pendant qu'il tourne; dans d'autres langages, le développeur doit +explicitement allouer et libérer la mémoire. Rust aborde une troisième +approche : la mémoire est gérée avec un système d'appropriation avec un jeu de +règles que le compilateur vérifie au moment de la compilation. Il n'y a pas +d'impact sur les performances au moment de l'exécution pour toutes les +fonctionnalités d'appropriation. + + + +Parce que l'appropriation est un nouveau principe pour de nombreux +développeurs, cela prend un certain temps à se familiariser. La bonne +nouvelle c'est que plus vous devenez expérimenté avec Rust et ses règles +d'appropriation, plus vous pourrez développer naturellement du code sûr et +efficace. Gardez bien cela à l'esprit ! + + + +Quand vous comprenez l'appropriation, vous aurez une base solide pour +comprendre les fonctionnalités qui font la singularité de Rust. Dans ce +chapitre, vous allez apprendre l'appropriation en travaillant sur plusieurs +exemples qui se concentrent sur une structure de données très courante : les +chaînes de caractères. + + + +> ### La Stack et la Heap +> +> Dans de nombreux langages, nous n'avons pas besoin souvent de penser à la +> Stack et la Heap. Mais dans un système de langage de programmation comme +> Rust, si une donnée est sur la Stack ou sur la Heap a plus d'effet sur +> comment le langage se comporte et pourquoi nous devons faire certains choix. +> Nous décrirons plus loin dans ce chapitre les différences entre la Stack et +> la Heap, voici donc une brève explication en attendant. +> +> La Stack et la Heap sont toutes les deux des emplacements de la mémoire qui +> sont à disposition de votre code lors de son exécution, mais elles sont +> construites de manière différentes. La Stack enregistre les valeurs dans +> l'ordre qu'elle les reçoit et enlève les valeurs dans l'autre sens. C'est +> ce que l'on appelle : *dernier entré, premier sorti*. C'est comme une pile +> d'assiettes : quand vous ajoutez des nouvelles assiettes, vous les déposez +> sur le dessus de la pile, et quand vous avez besoin d'une assiette, vous en +> prenez une sur le dessus. Ajouter ou enlever des assiettes au milieu ou en +> dessous ne serait pas aussi efficace ! Ajouter une donnée est appelé +> *pousser sur la Stack* et en enlever une se dit *sortir de la Stack*. +> +> La Stack est rapide grâce à la façon dont elle accède aux données : elle ne +> va jamais avoir besoin de chercher un emplacement pour y mettre des données, +> car c'est toujours au-dessus. Une autre caractéristique qui fait que la Stack +> est rapide c'est que toutes les données de la Stack doivent avoir une taille +> connue et fixe. +> +> Si les données ont une taille qui nous est inconnue au moment de la +> compilation ou une taille qui peut changer, nous pouvons plutôt les stocker +> dans la Heap. La Heap est moins organisée : quand nous poussons des données +> sur la Heap, nous demandons une certaine quantité de place. Le système +> d'exploitation trouve un emplacement vide suffisamment grand quelque part +> dans la Heap, le marque comme en cours d'utilisation, et nous retourne un +> *pointeur*, qui est l'adresse de cet emplacement. Ce processus est appellé +> *allouer de la place sur la Heap*, et parfois nous raccourcissons cette +> phrase à simplement *allouer*. Mais pousser des valeurs sur Stack n'est pas +> considéré comme allouer. Parce que le pointeur a une taille connue et fixée, +> nous pouvons stocker ce pointeur sur la Stack, mais quand nous voulons la +> donnée concernée, nous avons besoin de suivre le pointeur. +> +> C'est comme si vous vouliez manger à un restaurant. Quand vous entrez, vous +> indiquez le nombre de personnes dans votre groupe, et le personnel trouve une +> table vide qui peut recevoir tout le monde, et vous y conduit. Si quelqu'un +> dans votre groupe arrive en retard, il peut leur demander où vous êtes assis +> pour vous rejoindre. +> +> Accéder à des données dans la Heap est plus lent que d'accéder aux données +> sur la Stack car nous devons suivre un pointeur pour l'obtenir. Les +> processeurs modernes sont plus rapide s'ils sautent moins dans la mémoire. +> Pour continuer avec notre analogie, immaginez une serveur dans un restaurant +> qui prends les commandes de nombreuses tables. C'est plus efficace de +> récupérer toutes les commandes à une seule table avant de passer à la table +> suivante. Prendre une commande à la table A, puis prendre une commande à la +> table B, puis ensuite une à la table A à nouveau, puis suite une à la table B +> à nouveau sera un processus bien plus lent. De la même manière, un processeur +> sera plus efficace dans sa tâche s'il travaille sur des données qui sont +> proches l'une de l'autre (comme c'est sur la Stack) plutôt que si elles sont +> plus éloignées (comme cela peut être le cas sur la Heap). Allouer une grande +> quantité d'espace sur la Heap peut aussi prendre plus de temps. +> +> Quand notre code utilise une fonction, les valeurs envoyées à la fonction +> (incluant, potentiellement, des pointeurs vers des données sur la Heap) et +> les variables locales de la fonction sont poussées sur la Stack. Quand la +> fonction est terminée, ces données sont sorties de la Stack. +> +> Faire attention à telles parties du code utilise telles parties de données +> sur la Heap, minimiser la quantité de données en double sur la Heap, et +> libérer les données inutilisées sur la Heap pour que nous ne soyons pas à +> court d'espace, sont tous les problèmes que règle l'appropriation. Quand +> vous aurez compris l'appropriation, vous n'aurez plus souvent besoin de +> penser à la Stack et la Heap, mais savoir que l'appropriation existe pour +> gérer les données de la Heap, peut vous aider à comprendre pourquoi elle +> fonctionne de cette façon. + + + +### Les règles de l'appropriation + + + +Tout d'abord, définissons les règles de l'appropriation. Gardez à l'esprit ces +règles pendant que nous travaillons sur des exemples qui les illustrent : + + + +* Chaque valeur dans Rust a une variable qui s'appelle son *propriétaire*. +* Il ne peut y avoir qu'un seul propriétaire au même moment. +* Quand le propriétaire sort du bloc d'instructions, la valeur est supprimée. + + + +### Portée de la variable + + + +Nous avons déjà vu un exemple dans le programme Rust du Chapitre 2. Maintenant +que nous avons terminé la syntaxe de base, nous n'allons pas mettre tout le +code de `fn main() {` dans des exemples, donc si vous suivez, vous devez mettre +les exemples suivants manuellement dans une fonction `main`. De fait, nos +exemples seront plus concis, nous permettant de nous concentrer sur les détails +actuels plutôt que sur du code conventionnel. + + + +Pour le premier exemple d'appropriation, nous allons analyser la *portée* de +certaines variables. Une portée est une zone dans un programme dans lequel un +objet est en vigueur. Imaginons que nous avons une variable qui ressemble à +ceci : + +```rust +let s = "hello"; +``` + + + +La variable `s` fait référence à une chaîne de caractères pure, où la valeur de +la chaîne est codée en dur dans notre programme. La variable est en vigueur à +partir du point où elle est déclarée jusqu'à la fin de la *portée* actuelle. +L'entrée 4-1 a des commentaires pour indiquer quand la variable `s` est en +vigueur : + + + +```rust +{ // s n'est pas en vigueur ici, elle n'est pas encore déclarée + let s = "hello"; // s est en vigueur à partir de ce point + + // on fait des choses avec s ici +} // cette portée est maintenant terminée, et s n'est plus en vigueur +``` + + + +Entrée 4-1 : une variable et la portée dans laquelle elle +est en vigueur. + + + +Autrement dit, il y a ici deux étapes importantes : + + + +* Quand `s` rentre *dans la portée*, elle est en vigueur. +* Cela reste ainsi jusqu'à ce qu'elle *sort de la portée*. + + + +Pour le moment, la relation entre les portées et quand les variables sont en +vigueur sont similaires à d'autres langages de programmation. Maintenant nous +allons aller plus loin dans la compréhension en y ajoutant le type `String`. + + + +### Le type `String` + + + +Pour illustrer les règles de l'appartenance, nous avons besoin d'un type de +donnée qui est plus complexe que ceux que nous avons rencontré au chapitre 3. +Les types que nous avons vu dans la section “Types de données” sont toutes +stockées sur la Stack et sont sorties de la Stack quand elles sortent de la +portée, mais nous voulons examiner les données stockées sur la Heap et regarder +comment Rust sait quand il doit nettoyer ces données. + + + +Nous allons utiliser ici `String` pour l'exemple et nous concentrer sur les +éléments de `String` qui sont liés à l'appropriation. Ces caractéristiques +s'appliquent aussi pour d'autres types de données complexes fournies par la +librairie standard et celles que vous créez. Nous verrons `String` plus en +détail dans le Chapitre 8. + + + +Nous avons déjà vu les chaînes de caractères pures, quand une valeur de chaîne +est codée en dur dans notre programme. Les chaînes de caractères pures sont +pratiques, mais elles ne conviennent pas toujours à tous les cas où vous voulez +utiliser du texte. Une des raisons est qu'elle est immuable. Une autre est +qu'on ne connait pas forcément toutes les chaînes de caractères quand nous +écrivons notre code : par exemple, comment faire si nous voulons récupérer du +texte saisi par l'utilisateur et l'enregistrer ? Pour ces cas-ci, Rust a un +second type de chaîne de caractères, `String`. Ce type est alloué sur la Heap +et est ainsi capable de stocker une quantité de texte qui nous est inconnue au +moment de la compilation. Vous pouvez créer un `String` à partir d'une chaîne +de caractères pure en utilisant la fonction `from`, comme ceci : + +```rust +let s = String::from("hello"); +``` + + + +Le deux-points double est un opérateur qui nous permet d'appeler cette +fonction spécifique dans l'espace de nom du type `String` plutôt que d'utiliser +un nom comme `string_from`. Nous allons voir cette syntaxe plus en détail dans +la section “Syntaxe de méthode” du Chapitre 5 et lorsque nous allons aborder +l'espace de nom avec les modules au Chapitre 7. + + + +Ce type de chaîne de caractères *peut* être mutable : + + + +```rust +let mut s = String::from("hello"); + +s.push_str(", world!"); // push_str() ajoute du texte dans un String + +println!("{}", s); // Cela va afficher `hello, world!` +``` + + + +Donc, quelle est la différence ici ? Pourquoi `String` peut être mutable, mais +que les chaînes pures ne peuvent pas l'être ? La différence est comment ces +deux types travaillent avec la mémoire. + + + +### Mémoire et attribution + + + +Dans le cas d'une chaîne de caractères pure, nous connaissons le contenu au +moment de la compilation donc le texte est codé en dur directement dans +l'exécutable final, ce qui fait que ces chaînes de caractères pures sont +performantes et rapides. Mais ces caractéristiques viennent de leur +immuabilité. Malheureusement, nous ne pouvons pas stocker un blob de mémoire +dans le binaire pour chaque morceau de texte qui n'a pas de taille connue au +moment de la compilation et dont la taille pourrait changer pendant l'exécution +de ce programme. + + + +Avec le type `String`, afin de permettre un texte mutable et qui peut +s'aggrandir, nous devons allouer une quantité de mémoire sur la Heap, inconnue +au moment de la compilation, pour stocker le contenu. Cela signifie que : + + + +* La mémoire doit être sollicitée auprès du système d'exploitation lors de + l'exécution. +* Nous avons besoin d'un moyen de rendre cette mémoire au système + d'exploitation quand nous avons fini avec notre `String`. + + + +Le premier point est fait par nous : quand nous appelons `String::from`, sa +définition demande la mémoire dont elle a besoin. C'est pratiquement toujours +le cas dans les langages de programmation. + + + + +Cependant, le deuxième point est différent. Dans des langages avec un +*ramasse-miettes*, le ramasse-miettes surveille et nettoie la mémoire qui n'est +plus utilisée, sans que nous, les développeurs, nous ayons à nous en +préoccuper. Sans un ramasse-miettes, c'est de la responsabilité du développeur +d'identifier quand la mémoire n'est plus utilisée et d'appeler du code pour +explicitement la libérer, comme nous l'avons fait pour la demander auparavant. +Historiquement, faire ceci correctement a toujours été une difficulté pour +développer. Si nous oublions de le faire, nous allons gaspiller de la mémoire. +Si nous le faisons trop tôt, nous allons avoir une variable incorrecte. Si nous +le faisons deux fois, c'est aussi un bogue. Nous avons besoin d'associer +exactement un `allocate` avec exactement un `free`. + + + +Rust prends un chemin différent : la mémoire est automatiquement libérée dès +que la variable qui la possède sort de la portée. Voici une version de notre +exemple de portée de l'entrée 4-1 qui utilise un `String` plutôt qu'une chaîne +de caractères pure : + + + +```rust +{ + let s = String::from("hello"); // s est en vigueur à partir de ce point + + // on fait des choses avec s ici +} // cette portée est désormais finie, et s + // n'est plus en vigueur maintenant +``` + + + +Il y a un cas naturel auquel nous devons rendre la mémoire de notre `String` au +système d'exploitation : quand `s` sort de la portée. Quand une variable sort +de la portée, Rust utilise une fonction spéciale pour nous. Cette fonction +s'appelle `drop`, et ceci que l'auteur du `String` peut le mettre dans le code +pour libérer la mémoire. Rust utilise automatiquement `drop` à l'accolade +fermante `}`. + + + +> Note : dans du C++, cette façon de libérer des ressources à la fin de la +> durée de vie d'un objet est parfois appelé *Resource Acquisition Is +> Initialization (RAII)*. La fonction `drop` de Rust vous sera familière si +> vous avez déjà utilisé des fonctions de RAII. + + + +Cette façon de faire a un impact profond sur la façon dont le code de Rust est +écrit. Cela peut sembler simple ici, mais le comportement du code peut être +inattendu dans des situations plus compliquées quand nous voulons avoir +plusieurs variables avec des données que nous avons allouées sur la Heap. +Examinons une de ces situations dès à présent. + + + +#### Les interactions entre les variables et les données : les déplacements + + + +Plusieurs variables peuvent interagir avec les mêmes données de différentes +manières avec Rust. Regardons un exemple avec un entier dans l'entrée 4-2 : + +```rust +let x = 5; +let y = x; +``` + + + +Entrée 4-2 : assigner la valeur entière de la variable +`x` à la `y` + + + +Nous pouvons deviner ce qui va probablement se passer grâce à notre expérience +avec d'autres langages : “Assigner la valeur `5` à `x`; ensuite faire une copie +de la valeur de `x` et l'assigner à `y`.” Nous avons maintenant deux variables, +`x` et `y`, et toutes les deux sont égales à `5`. C'est effectivement ce qui se +passe, car les entiers sont des valeurs simples avec une taille connue et +fixée, et ces deux valeurs `5` sont stockées sur la Stack. + + + +Maintenant, regardons une nouvelle version avec `String` : + +```rust +let s1 = String::from("hello"); +let s2 = s1; +``` + + + +Cela ressemble beaucoup au code précédent, donc nous allons supposer que cela +fonctionne pareil que précédemment : ainsi, la seconde ligne va faire une copie +de la valeur dans `s1` et l'assigner à `s2`. Mais ce n'est pas tout à fait ce +qu'il se passe. + + + +Pour expliquer cela plus précisément, regardons à quoi ressemble `String` avec +l'illustration 4-1. Un `String` est constitué de trois éléments, présentes sur +la gauche : un pointeur vers la mémoire qui contient le contenu de la chaîne +de caractères, une taille, et une capacité. Ces données sont stockées sur la +Stack. Sur la droite est la mémoire sur la Heap qui contient les données. + +String in memory + + + +Illustration 4-1 : représentation d'un `String` dans la +mémoire qui contient la valeur `"hello"` assignée à `s1`. + + + +La taille est combien de mémoire, en octets, le contenu du `String` utilise +actuellement. La capacité est la quantité totale de mémoire, en octets, que +`String` a reçu du système d'exploitation. La différence entre la taille et la +capacité est importante, mais pas dans ce contexte, donc pour l'instant, ce +n'est pas grave de mettre de côté la capacité. + + + +Quand nous assignons `s1` à `s2`, les données de `String` sont copiées, ce qui +veut dire que nous copions le pointeur, la taille, et la capacité qu'il y a sur +la Stack. Mais nous ne copions pas les données sur la Heap dont fait référence +le pointeur. Autrement dit, la représentation des données dans la mémoire +ressemble à l'illustration 4-2. + +s1 and s2 pointing to the same value + + + +Illustration 4-2 : représentation dans la mémoire de la +variable `s2` qui est une copie du pointeur, taille et capacité de `s1` + + + +La représentation *n'est pas* comme l'illustration 4-3, qui serait la mémoire +si Rust avait aussi copié les données sur la Heap. Si Rust fait cela, +l'opération `s2 = s1` pourrait potentiellement être coûteuse en termes de +performances d'exécution si les données sur la Heap étaient grosses. + +s1 and s2 to two places + + + +Illustration 4-3 : une autre possibilité de ce que +pourrait faire `s2 = s1` si Rust copiait aussi les données sur la Heap + + + +Auparavant, nous avons que quand une variable sort de la portée, Rust appelait +automatiquement la fonction `drop` et nettoyait la mémoire sur la Heap +concernant cette variable. Mais l'illustration 4-2 montre que les deux +pointeurs de données pointaient au même endroit. C'est un problème : quand +`s2` et `s1` sortent de la portée, elles vont essayer toutes les deux de +libérer la même mémoire. C'est ce qu'on appelle une erreur de *double +libération* et c'est un des bogues de sécurité de mémoire que nous avons +mentionné précédemment. Libérer la mémoire deux fois peut mener à des +corruptions de mémoire, qui peut potentiellement mener à des vulnérabilités +de sécurité. + + + +Pour garantir la sécurité de la mémoire, il y a un autre détail en plus qui se +passe dans cette situation avec Rust. Plutôt qu'essayer de copier la mémoire +allouée, Rust considère que `s1` n'est plus en vigueur et du fait, Rust n'a pas +besoin de libérer quoi que ce soit lorsque `s1` sort de la portée. Regardes ce +qu'il se passe quand vous essayez d'utiliser `s1` après que `s2` soit créé, +cela ne va pas fonctionner : + +```rust,ignore,does_not_compile +let s1 = String::from("hello"); +let s2 = s1; + +println!("{}, world!", s1); +``` + + + +Vous allez avoir une erreur comme celle-ci, car Rust vous défends d'utiliser la +référence qui n'est plus en vigueur : + +```text +error[E0382]: use of moved value: `s1` + -- > src/main.rs:5:28 + | +3 | let s2 = s1; + | -- value moved here +4 | +5 | println!("{}, world!", s1); + | ^^ value used here after move + | + = note: move occurs because `s1` has type `std::string::String`, which does + not implement the `Copy` trait +``` + + + +Si vous avez déjà entendu parler de “copie de surface” et de “copie en +profondeur” en utilisant d'autres langages, l'idée de copier le pointeur, la +taille et la capacité sans copier les données peut vous faire penser à de la +copie de surface. Mais parce que Rust invalide aussi la première variable, au +lieu d'appeler cela une copie de surface, on appelle cela un *déplacement*. +Ici nous pourrions lire ainsi en disant que `s1` a été *déplacé* dans `s2`. +Donc ce qui se passe réellement est montré dans l'illustration 4-4. + +s1 moved to s2 + + + +Illustration 4-4 : Représentation de la mémoire après que +`s1` a été invalidé + + + +Cela résout notre problème ! Avec seulement `s2` en vigueur, quand elle +sortira de la portée, elle seule va libérer la mémoire, et c'est tout. + + + +De plus, cela signifie qu'il y a eu un choix de conception : Rust ne va jamais +créer des copies “profondes” de vos données. Par conséquent, toute copie +*automatique* peut être considérée comme peu coûteuse en termes de performances +d'exécution. + + + +#### Les interactions entre les variables et les données : le clonage + + + +Si nous *voulons* faire une copie profonde des données sur la Heap d'un +`String`, et pas seulement des données sur la Stack, nous pouvons utiliser une +méthode courante qui s'appelle `clone`. Nous allons aborderons la syntaxe des +méthodes dans le chapitre 5, mais parce que les méthodes sont un outil courant +dans de nombreux langages, vous les avez probablement utilisé auparavant. + + + +Voici un exemple d'utilisation de la méthode `clone` : + +```rust +let s1 = String::from("hello"); +let s2 = s1.clone(); + +println!("s1 = {}, s2 = {}", s1, s2); +``` + + + +Cela fonctionne très bien et c'est ainsi que vous pouvez reproduire le +comportement décrit dans l'illustration 4-3, dans les données de la Heap sont +copiées. + + + +Quand vous voyez un appel à `clone`, vous savez que du code arbitraire est +exécuté et que ce code peu coûteux. C'est un indicateur visuel qu'il se passe +quelque chose de différent. + + + +#### Données seulement sur la Stack : les copier + + + +Il y a une autre faille dont on n'a pas encore parlé. Le code suivant utilise +des entiers, dont une partie a déjà été montré dans l'entrée 4-2, il fonctionne +et est correct : + +```rust +let x = 5; +let y = x; + +println!("x = {}, y = {}", x, y); +``` + + + +Mais ce code semble contredire ce que nous venons d'apprendre : nous n'avons +pas appelé un `clone`, mais `x` est toujours en vigueur et n'a pas été déplacé +dans `y`. + + + +La raison est que ces types tels que les entiers ont une taille connue au +moment de la compilation et sont entièrement stockées sur la Stack, donc copie +les valeurs actuelles, ce qui est rapide à faire. Cela signifie qu'il n'y a pas +de raison que nous voudrions empêcher `x` d'être toujours en vigueur après +avoir créé la variable `y`. En d'autres termes, ici il n'y a pas de différence +entre la copie en surface et profonde, donc appeler `clone` ne ferait rien de +différent que la copie en surface habituelle et nous pouvons l'exclure. + + + +Rust a une annotation spéciale appelée le trait `Copy` que nous pouvons +utiliser sur des types comme les entiers qui sont stockés sur la Stack (nous +verrons les traits dans le chapitre 10). Si un type a le trait `Copy`, +l'ancienne variable est toujours utilisable après son affectation. Rust ne pas +nous autoriser à annoter type avec le trait `Copy` si ce type, ou un de ses +éléments, a implémenté le trait `Drop`. Si ce type a besoin que quelque chose +de spécial se passe quand la valeur sort de la portée et que nous ajoutons +l'annotation `Copy` sur ce type, nous allons avoir une erreur au moment de la +compilation. Pour en savoir plus sur comment ajouter l'annotation `Copy` sur +votre type, reférez-vous à l'annexe C sur les traits dérivés. + + + + +Donc, quels sont les types qui ont `Copy` ? Vous pouvez regarder dans la +documentation pour un type donné pour vous en assurer, mais de manière +générale, tout groupe de simple scalaire peut être `Copy`, (TODO) and nothing that requires allocation or is some form of resource is `Copy`. +Voici quelques types qui sont `Copy` : + + + +* Tous les types d'entiers, comme `u32`. +* Le type booléen, `bool`, avec les valeurs `true` et `false`. +* Le type de caractères, `char`. +* Tous les types de nombres à virgule, comme `f64`. +* Les Tuples, mais uniquement s'ils contiennent des types qui sont aussi + `Copy`. Le `(i32, i32)` est `Copy`, mais `(i32, String)` ne l'est pas. + + + +### L'appropriation et les fonctions + + + +La syntaxe pour passer une valeur à une fonction est similaire à celle pour +assigner une valeur à une variable. Passer une variable à une fonction va la +déplacer ou la copier, comme l'assignation. L'entrée 4-3 est un exemple avec +quelques commentaires qui montrent où les variables rentrent et sortent de la +portée : + + + +Nom du fichier : src/main.rs + + + +```rust +fn main() { + let s = String::from("hello"); // s rentre dans la portée. + + takes_ownership(s); // La valeur de s est déplacée dans la fonction ... + // ... et n'est plus en vigueur à partir d'ici + + let x = 5; // x rentre dans la portée. + + makes_copy(x); // x va être déplacée dans la fonction, + // mais i32 implémente Copy, donc on peux + // utiliser x ensuite. + +} // Ici, x sort de la portée, puis ensuite s. Mais puisque la valeur de s a + // été déplacée, il ne se passe rien de spécial. + + +fn takes_ownership(some_string: String) { // some_string rentre dans la portée. + println!("{}", some_string); +} // Ici, some_string sort de la portée et `drop` est appellé. La mémoire est + // libérée. + +fn makes_copy(some_integer: i32) { // some_integer rentre dans la portée. + println!("{}", some_integer); +} // Ici, some_integer sort de la portée. Il ne se passe rien de spécial. +``` + + + +Entrée 4-3 : les fonctions avec les appartenances et les +portées qui sont commentées + + + +Si nous essayons d'utiliser `s` après l'appel à `takes_ownership`, Rust va +lever et retourner une erreur au moment de la compilation. Ces vérifications +statiques nous protègent des erreurs. Essayez d'ajouter du code au `main` qui +utilise `s` et `x` pour voir quand vous pouvez les utiliser et quand les règles +de l'appartenance vous empêchent de le faire. + + + +### Les valeurs de retour et la portée + + + +Renvoyer les valeurs peut aussi transférer leur appartenance. Voici un exemple +avec des annotations similaires à celles de l'entrée 4-3 : + + + +Nom du fichier : src/main.rs + + + +```rust +fn main() { + let s1 = gives_ownership(); // gives_ownership déplace sa valeur de + // retour dans s1 + + let s2 = String::from("hello"); // s2 rentre dans la portée + + let s3 = takes_and_gives_back(s2); // s2 est déplacée dans + // takes_and_gives_back, qui elle aussi + // déplace sa valeur de retour dans s3. +} // Ici, s3 sort de la portée et est éliminée. s2 sort de la portée mais a été + // déplacée donc il ne se passe rien. s1 sort aussi de la portée et est + // éliminée. + +fn gives_ownership() -> String { // gives_ownership va déplacer sa + // valeur de retour dans la + // fonction qui l'appelle. + + let some_string = String::from("hello"); // some_string rentre dans la + //portée. + + some_string // some_string est retrournée et + // est déplacée au code qui + // l'appelle. +} + +// takes_and_gives_back va prendre un String et retourne aussi un String. +fn takes_and_gives_back(a_string: String) -> String { // a_string rentre dans + // la portée. + + a_string // a_string est retournée et déplacée au code qui l'appelle. +} +``` + +Listing 4-4: Transferring ownership of return +values + + + +L'appartenance d'une variable suit toujours le même processus à chaque fois : +assigner une valeur à une variable la déplace. Quand une variable qui contient +des données sur la Heap sort de la portée, la valeur va être nettoyée de la +mémoire avec `drop` à moins que la donnée aie été déplacée pour appartenir à +une autre variable. + + + +Il est un peu fastidieux de prendre l'appartenance puis ensuite de retourner +l'appartenance avec chaque fonction. Et qu'est ce qu'il se passe si nous +voulons qu'une fonction utilise une valeur, mais ne se l'approprie pas ? C'est +assez pénible que tout ce que nous envoyons doit être retourné si nous voulons +l'utiliser à nouveau, en plus de toutes les données qui découlent de +l'exécution de la fonction que nous voulons aussi récupérer. + + + +Il est possible de retourner plusieurs valeurs en utilisant un tuple, comme +ceci : + + + +Nom du fichier : src/main.rs + + + + +```rust +fn main() { + let s1 = String::from("hello"); + + let (s2, len) = calculate_length(s1); + + println!("The length of '{}' is {}.", s2, len); +} + +fn calculate_length(s: String) -> (String, usize) { + let length = s.len(); // len() renvoie le nombre de caractères d'un String. + + (s, length) +} +``` + +Listing 4-5: Returning ownership of parameters + + + +Mais c'est trop de cérémonies et beaucoup de travail pour un principe qui +devrait être courant. Heureusement pour nous, Rust a une fonctionnalité pour +ce principe, et c'est ce qu'on appelle les *références*. + +[data-types]: ch03-02-data-types.html#data-types +[derivable-traits]: appendix-03-derivable-traits.html +[method-syntax]: ch05-03-method-syntax.html#method-syntax +[paths-module-tree]: ch07-03-paths-for-referring-to-an-item-in-the-module-tree.html diff --git a/FRENCH/src/img/trpl04-01.svg b/FRENCH/src/img/trpl04-01.svg new file mode 100644 index 0000000000..314f53ba12 --- /dev/null +++ b/FRENCH/src/img/trpl04-01.svg @@ -0,0 +1,68 @@ + + + + + + +%3 + + + +table0 + +s1 + +name + +value + +ptr + + +len + +5 + +capacity + +5 + + + +table1 + +index + +value + +0 + +h + +1 + +e + +2 + +l + +3 + +l + +4 + +o + + + +table0:c->table1:pointee + + + + + diff --git a/FRENCH/src/img/trpl04-02.svg b/FRENCH/src/img/trpl04-02.svg new file mode 100644 index 0000000000..70d490f0bc --- /dev/null +++ b/FRENCH/src/img/trpl04-02.svg @@ -0,0 +1,95 @@ + + + + + + +%3 + + + +table0 + +s1 + +name + +value + +ptr + + +len + +5 + +capacity + +5 + + + +table1 + +index + +value + +0 + +h + +1 + +e + +2 + +l + +3 + +l + +4 + +o + + + +table0:c->table1:pointee + + + + + +table3 + +s2 + +name + +value + +ptr + + +len + +5 + +capacity + +5 + + + +table3:c->table1:pointee + + + + + diff --git a/FRENCH/src/img/trpl04-03.svg b/FRENCH/src/img/trpl04-03.svg new file mode 100644 index 0000000000..7c153e23a3 --- /dev/null +++ b/FRENCH/src/img/trpl04-03.svg @@ -0,0 +1,123 @@ + + + + + + +%3 + + + +table0 + +s2 + +name + +value + +ptr + + +len + +5 + +capacity + +5 + + + +table1 + +index + +value + +0 + +h + +1 + +e + +2 + +l + +3 + +l + +4 + +o + + + +table0:c->table1:pointee + + + + + +table3 + +s1 + +name + +value + +ptr + + +len + +5 + +capacity + +5 + + + +table4 + +index + +value + +0 + +h + +1 + +e + +2 + +l + +3 + +l + +4 + +o + + + +table3:c->table4:pointee + + + + + diff --git a/FRENCH/src/img/trpl04-04.svg b/FRENCH/src/img/trpl04-04.svg new file mode 100644 index 0000000000..a0513abd90 --- /dev/null +++ b/FRENCH/src/img/trpl04-04.svg @@ -0,0 +1,96 @@ + + + + + + +%3 + + + +table0 + + +s1 + +name + +value + +ptr + + +len + +5 + +capacity + +5 + + + +table1 + +index + +value + +0 + +h + +1 + +e + +2 + +l + +3 + +l + +4 + +o + + + +table0:c->table1:pointee + + + + + +table3 + +s2 + +name + +value + +ptr + + +len + +5 + +capacity + +5 + + + +table3:c->table1:pointee + + + + + From dae2be6e5cfc037838c63e2b0719eb46e6bd925e Mon Sep 17 00:00:00 2001 From: Akhilesh Singhania Date: Sun, 18 Aug 2019 21:24:11 +0200 Subject: [PATCH 046/117] Minor: remove an extraneous `.` --- src/ch15-03-drop.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ch15-03-drop.md b/src/ch15-03-drop.md index 800de36bfc..d081bb49c1 100644 --- a/src/ch15-03-drop.md +++ b/src/ch15-03-drop.md @@ -58,7 +58,7 @@ an instance of your type goes out of scope. We’re printing some text here to demonstrate when Rust will call `drop`. In `main`, we create two instances of `CustomSmartPointer` and then print -`CustomSmartPointers created.`. At the end of `main`, our instances of +`CustomSmartPointers created`. At the end of `main`, our instances of `CustomSmartPointer` will go out of scope, and Rust will call the code we put in the `drop` method, printing our final message. Note that we didn’t need to call the `drop` method explicitly. From e9afa40ead32b696de5753394511640cef91b9b5 Mon Sep 17 00:00:00 2001 From: Jimskapt Date: Mon, 19 Aug 2019 12:54:02 +0200 Subject: [PATCH 047/117] :ambulance: Self-proofreading and updating translation of ch04-01. --- FRENCH/src/SUMMARY.md | 2 + FRENCH/src/ch04-01-what-is-ownership.md | 649 ++++++++++++------------ FRENCH/src/translation-terms.md | 21 + 3 files changed, 351 insertions(+), 321 deletions(-) diff --git a/FRENCH/src/SUMMARY.md b/FRENCH/src/SUMMARY.md index 45cc984e60..8490daf16b 100644 --- a/FRENCH/src/SUMMARY.md +++ b/FRENCH/src/SUMMARY.md @@ -10,3 +10,5 @@ - [Installation](ch01-01-installation.md) - [Hello, world!](ch01-02-hello-world.md) - [Hello, Cargo!](ch01-03-hello-cargo.md) + +- [Qu'est-ce que la possession ?](ch04-01-what-is-ownership.md) \ No newline at end of file diff --git a/FRENCH/src/ch04-01-what-is-ownership.md b/FRENCH/src/ch04-01-what-is-ownership.md index f50fc0752e..e56962bc9b 100644 --- a/FRENCH/src/ch04-01-what-is-ownership.md +++ b/FRENCH/src/ch04-01-what-is-ownership.md @@ -2,14 +2,14 @@ ## What Is Ownership? --> -## Qu'est-ce que l'appropriation ? +## Qu'est-ce que la possession ? -La fonctionnalité centrale de Rust est *l'appropriation*. Bien que cette +La principale spécificité de Rust est *la possession*. Bien que cette fonctionnalité soit simple à expliquer, elle a de profondes conséquences sur le reste du langage. @@ -24,14 +24,13 @@ running. --> Tous les programmes doivent gérer la façon dont ils utilisent la mémoire -(vive, RAM) de l'ordinateur lorsqu'ils s'exécutent. Certains langages ont un -ramasse-miettes qui scrute constamment la mémoire qui n'est plus utilisée par -le programme pendant qu'il tourne; dans d'autres langages, le développeur doit -explicitement allouer et libérer la mémoire. Rust aborde une troisième -approche : la mémoire est gérée avec un système d'appropriation avec un jeu de -règles que le compilateur vérifie au moment de la compilation. Il n'y a pas -d'impact sur les performances au moment de l'exécution pour toutes les -fonctionnalités d'appropriation. +lorsqu'ils s'exécutent. Certains langages ont un ramasse-miettes qui scrute +constamment la mémoire qui n'est plus utilisée pendant qu'il s'exécute; dans +d'autres langages, le développeur doit explicitement allouer et libérer la +mémoire. Rust adopte une troisième approche : la mémoire est gérée avec un +système de possession qui repose sur un jeu de règles que le compilateur vérifie +au moment de la compilation. Il n'y a pas d'impact sur les performances pendant +l'exécution pour toutes les fonctionnalités de possession. -Parce que l'appropriation est un nouveau principe pour de nombreux -développeurs, cela prend un certain temps à se familiariser. La bonne -nouvelle c'est que plus vous devenez expérimenté avec Rust et ses règles -d'appropriation, plus vous pourrez développer naturellement du code sûr et -efficace. Gardez bien cela à l'esprit ! +Comme la possession est un nouveau principe pour de nombreux développeurs, +cela prend un certain temps pour s'y familiariser. La bonne nouvelle est que +plus vous devenez expérimenté avec Rust et ses règles de possession, plus vous +développerez naturellement du code sûr et efficace. Gardez bien cela à +l'esprit ! -Quand vous comprenez l'appropriation, vous aurez une base solide pour -comprendre les fonctionnalités qui font la singularité de Rust. Dans ce -chapitre, vous allez apprendre l'appropriation en travaillant sur plusieurs -exemples qui se concentrent sur une structure de données très courante : les +Lorsque vous comprendrez la possession, vous aurez des base solide pour +comprendre les fonctionnalités qui font la particularité de Rust. Dans ce +chapitre, vous allez apprendre la possession en pratiquant avec plusieurs +exemples qui se concentrent sur une structure de données très courante : les chaînes de caractères. -> ### La Stack et la Heap +> ### La pile et le tas > -> Dans de nombreux langages, nous n'avons pas besoin souvent de penser à la -> Stack et la Heap. Mais dans un système de langage de programmation comme -> Rust, si une donnée est sur la Stack ou sur la Heap a plus d'effet sur -> comment le langage se comporte et pourquoi nous devons faire certains choix. -> Nous décrirons plus loin dans ce chapitre les différences entre la Stack et -> la Heap, voici donc une brève explication en attendant. +> Dans de nombreux langages, il n'est pas nécessaire de se préoccupper de la +> pile et du tas. Mais dans un système de langage de programmation comme +> Rust, si une donnée est sur la pile ou sur le tas influe le comportement du +> langage et explique pourquoi nous devons faire certains choix. Nous décrirons +> plus loin dans ce chapitre les différences entre la pile et le tas, voici +> donc une brève explication en attendant. > -> La Stack et la Heap sont toutes les deux des emplacements de la mémoire qui -> sont à disposition de votre code lors de son exécution, mais elles sont -> construites de manière différentes. La Stack enregistre les valeurs dans -> l'ordre qu'elle les reçoit et enlève les valeurs dans l'autre sens. C'est -> ce que l'on appelle : *dernier entré, premier sorti*. C'est comme une pile -> d'assiettes : quand vous ajoutez des nouvelles assiettes, vous les déposez -> sur le dessus de la pile, et quand vous avez besoin d'une assiette, vous en -> prenez une sur le dessus. Ajouter ou enlever des assiettes au milieu ou en -> dessous ne serait pas aussi efficace ! Ajouter une donnée est appelé -> *pousser sur la Stack* et en enlever une se dit *sortir de la Stack*. +> La pile et le tas sont tous les deux des emplacements de la mémoire qui +> sont à disposition de votre code lors de son exécution, mais sont organisés de +> façon différents. La pile enregistre les valeurs dans l'ordre qu'elle le +> reçoit et enlève les valeurs dans l'autre sens. C'est ce que l'on appelle le +> principe de *dernier entré, premier sorti*. C'est comme une pile d'assiettes : +> quand vous ajoutez des nouvelles assiettes, vous les déposez sur le dessus de +> la pile, et quand vous avez besoin d'une assiette, vous en prenez une sur le +> dessus. Ajouter ou enlever des assiettes au milieu ou en bas ne serait pas +> aussi efficace ! Ajouter une donnée est ainsi appelé *déposer sur la pile* et +> en enlever une se dit *retirer de la pile*. +> +> Toutes les données stockées dans la pile doivent avoir une taille connue et +> fixe. Les données avec une taille inconnue au moment de la compilation ou une +> taille qui peut changer doivent plutôt être stockées sur le tas. Le tas est +> moins bien organisé : lorsque vous ajoutez des données sur le tas, vous +> demandez une certaine quantité d'espace mémoire. Le système d'exploitation va +> trouver un emplacement dans le tas qui est suffisamment grand, va le marquer +> comme étant en cours d'utilisation, et va retourner un *pointeur*, qui est +> l'adresse de cet emplacement. Cette procédure est appelée *affecter de la +> place sur le tas*, et parfois nous raccourcissons cette phrase à simplement +> *affectation*. Pousser des valeurs sur la pile n'est pas considéré comme +> une affectation. Comme le pointeur a une taille connue et fixe, nous pouvons +> stocker ce pointeur sur la pile, mais quand nous voulons la donnée souhaitée, +> nous avons devons suivre le pointeur. > -> La Stack est rapide grâce à la façon dont elle accède aux données : elle ne -> va jamais avoir besoin de chercher un emplacement pour y mettre des données, -> car c'est toujours au-dessus. Une autre caractéristique qui fait que la Stack -> est rapide c'est que toutes les données de la Stack doivent avoir une taille -> connue et fixe. -> -> Si les données ont une taille qui nous est inconnue au moment de la -> compilation ou une taille qui peut changer, nous pouvons plutôt les stocker -> dans la Heap. La Heap est moins organisée : quand nous poussons des données -> sur la Heap, nous demandons une certaine quantité de place. Le système -> d'exploitation trouve un emplacement vide suffisamment grand quelque part -> dans la Heap, le marque comme en cours d'utilisation, et nous retourne un -> *pointeur*, qui est l'adresse de cet emplacement. Ce processus est appellé -> *allouer de la place sur la Heap*, et parfois nous raccourcissons cette -> phrase à simplement *allouer*. Mais pousser des valeurs sur Stack n'est pas -> considéré comme allouer. Parce que le pointeur a une taille connue et fixée, -> nous pouvons stocker ce pointeur sur la Stack, mais quand nous voulons la -> donnée concernée, nous avons besoin de suivre le pointeur. -> > C'est comme si vous vouliez manger à un restaurant. Quand vous entrez, vous > indiquez le nombre de personnes dans votre groupe, et le personnel trouve une > table vide qui peut recevoir tout le monde, et vous y conduit. Si quelqu'un > dans votre groupe arrive en retard, il peut leur demander où vous êtes assis > pour vous rejoindre. +> +> Déposer sur la pile est plus rapide qu'affecter sur le tas car le système +> d'exploitation ne va jamais avoir besoin de chercher un emplacement pour y +> stocker les nouvelles données; car c'est toujours au-dessus de la pile. En +> comparaison, allouer de la place sur le tas demande plus de travail, car le +> système d'exploitation doit d'abord trouver un espace assez grand pour stocker +> les données et mettre à jour son suivi pour préparer la prochaine affectation. > -> Accéder à des données dans la Heap est plus lent que d'accéder aux données -> sur la Stack car nous devons suivre un pointeur pour l'obtenir. Les -> processeurs modernes sont plus rapide s'ils sautent moins dans la mémoire. -> Pour continuer avec notre analogie, immaginez une serveur dans un restaurant -> qui prends les commandes de nombreuses tables. C'est plus efficace de -> récupérer toutes les commandes à une seule table avant de passer à la table -> suivante. Prendre une commande à la table A, puis prendre une commande à la -> table B, puis ensuite une à la table A à nouveau, puis suite une à la table B -> à nouveau sera un processus bien plus lent. De la même manière, un processeur -> sera plus efficace dans sa tâche s'il travaille sur des données qui sont -> proches l'une de l'autre (comme c'est sur la Stack) plutôt que si elles sont -> plus éloignées (comme cela peut être le cas sur la Heap). Allouer une grande -> quantité d'espace sur la Heap peut aussi prendre plus de temps. -> +> Accéder à des données dans le tas est plus lent que d'accéder aux données sur +> la pile car nous devons suivre un pointeur pour l'obtenir. Les processeurs +> modernes sont plus rapides s'ils se déplacent moins dans la mémoire. Pour +> continuer avec notre analogie, imaginez une serveur dans un restaurant qui +> prend les commandes de nombreuses tables. C'est plus efficace de récupérer +> toutes les commandes à une seule table avant de passer à la table suivante. +> Prendre une commande à la table A, puis prendre une commande à la table B, +> puis ensuite une autre à la table A, puis une autre à la table B serait un +> processus bien plus lent. De la même manière, un processeur sera plus efficace +> dans sa tâche s'il travaille sur des données qui sont proches l'une de l'autre +> (comme c'est le cas sur la pile) plutôt que si elles sont plus éloignées +> (comme cela peut être le cas sur le tas). Affecter une grande quantité +> d'espace sur le tas peut aussi prendre beaucoup de temps. +> > Quand notre code utilise une fonction, les valeurs envoyées à la fonction -> (incluant, potentiellement, des pointeurs vers des données sur la Heap) et -> les variables locales de la fonction sont poussées sur la Stack. Quand la -> fonction est terminée, ces données sont sorties de la Stack. -> -> Faire attention à telles parties du code utilise telles parties de données -> sur la Heap, minimiser la quantité de données en double sur la Heap, et -> libérer les données inutilisées sur la Heap pour que nous ne soyons pas à -> court d'espace, sont tous les problèmes que règle l'appropriation. Quand -> vous aurez compris l'appropriation, vous n'aurez plus souvent besoin de -> penser à la Stack et la Heap, mais savoir que l'appropriation existe pour -> gérer les données de la Heap, peut vous aider à comprendre pourquoi elle -> fonctionne de cette façon. +> (incluant, potentiellement, des pointeurs de données sur le tas) et les +> variables locales à la fonction sont déposées sur la pile. Quand l'utilisation +> de la fonction est terminée, ces données sont retirées de la pile. +> +> La possession nous aide à ne pas nous préoccuper de faire attention à quelles +> parties du code utilisent quelles de données sur le tas, de minimiser la +> quantité de données en double sur le tas, ou encore de veiller à libérer les +> données inutilisées sur le tas pour que nous ne soyons pas à court d'espace. +> Quand vous aurez compris la possession, vous n'aurez plus besoin de vous +> préoccuper de la pile et du tas, mais savoir que la possession existe pour +> gérer les données du tas peut vous aider à comprendre pourquoi elle fonctionne +> de cette manière. -### Les règles de l'appropriation +### Les règles de la possession -Tout d'abord, définissons les règles de l'appropriation. Gardez à l'esprit ces -règles pendant que nous travaillons sur des exemples qui les illustrent : +Tout d'abord, définissons les règles de la possession. Gardez à l'esprit ces +règles pendant que nous travaillons sur des exemples qui les illustrent : -Nous avons déjà vu un exemple dans le programme Rust du Chapitre 2. Maintenant -que nous avons terminé la syntaxe de base, nous n'allons pas mettre tout le -code de `fn main() {` dans des exemples, donc si vous suivez, vous devez mettre -les exemples suivants manuellement dans une fonction `main`. De fait, nos -exemples seront plus concis, nous permettant de nous concentrer sur les détails -actuels plutôt que sur du code conventionnel. +Nous avons déjà vu un exemple dans le programme Rust du chapitre 2. Maintenant +que nous avons vu la syntaxe Rust de base, nous n'allons plus ajouter tout le +code autour de `fn main() {` dans des exemples, donc si vous voulez reproduire +les exemples, vous devrez les mettre manuellement dans une fonction `main`. Par +conséquent, nos exemples seront plus concis, nous permettant de nous concentrer +sur les détails de la situation plutôt que sur du code normalisé. -Pour le premier exemple d'appropriation, nous allons analyser la *portée* de +Pour le premier exemple de possession, nous allons analyser la *portée* de certaines variables. Une portée est une zone dans un programme dans lequel un -objet est en vigueur. Imaginons que nous avons une variable qui ressemble à -ceci : +élément est en vigueur. Imaginons que nous avons la variable suivante : ```rust let s = "hello"; @@ -269,8 +269,8 @@ comments annotating where the variable `s` is valid. La variable `s` fait référence à une chaîne de caractères pure, où la valeur de la chaîne est codée en dur dans notre programme. La variable est en vigueur à partir du point où elle est déclarée jusqu'à la fin de la *portée* actuelle. -L'entrée 4-1 a des commentaires pour indiquer quand la variable `s` est en -vigueur : +L'encart 4-1 a des commentaires pour indiquer quand la variable `s` est en +vigueur : -Entrée 4-1 : une variable et la portée dans laquelle elle +Encart 4-1 : une variable et la portée dans laquelle elle est en vigueur. -Autrement dit, il y a ici deux étapes importantes : +Autrement dit, il y a ici deux étapes importantes : -Pour le moment, la relation entre les portées et quand les variables sont en -vigueur sont similaires à d'autres langages de programmation. Maintenant nous -allons aller plus loin dans la compréhension en y ajoutant le type `String`. +Pour le moment, la relation entre les portées et les conditions pour lesquelles +les variables sont en vigueur sont similaires à d'autres langages de +programmation. Maintenant nous allons aller plus loin en y ajoutant le type +`String`. -Pour illustrer les règles de l'appartenance, nous avons besoin d'un type de -donnée qui est plus complexe que ceux que nous avons rencontré au chapitre 3. -Les types que nous avons vu dans la section “Types de données” sont toutes -stockées sur la Stack et sont sorties de la Stack quand elles sortent de la -portée, mais nous voulons examiner les données stockées sur la Heap et regarder -comment Rust sait quand il doit nettoyer ces données. +Pour illustrer les règles de la possession, nous avons besoin d'un type de +donnée qui est plus complexe que ceux que nous avons rencontré dans la section +[“Types de données”][data-types] du chapitre 3. Les types que +nous avons vu précédemment sont tous stockées sur la pile et sont retirés de la +pile quand ils sortent de la portée, mais nous voulons expérimenter les données +stockées sur le tas et découvrir comment Rust sait quand il doit nettoyer ces +données. Nous allons utiliser ici `String` pour l'exemple et nous concentrer sur les -éléments de `String` qui sont liés à l'appropriation. Ces caractéristiques -s'appliquent aussi pour d'autres types de données complexes fournies par la -librairie standard et celles que vous créez. Nous verrons `String` plus en -détail dans le Chapitre 8. +éléments de `String` qui sont liés à la possession. Ces caractéristiques +s'appliquent également à d'autres types de données complexes fournies par la +bibliothèque standard et celles que vous créez. Nous verrons `String` plus en +détail dans le chapitre 8. -Le deux-points double est un opérateur qui nous permet d'appeler cette +Le double deux-points (`::`) est un opérateur qui nous permet d'appeler cette fonction spécifique dans l'espace de nom du type `String` plutôt que d'utiliser un nom comme `string_from`. Nous allons voir cette syntaxe plus en détail dans -la section “Syntaxe de méthode” du Chapitre 5 et lorsque nous allons aborder -l'espace de nom avec les modules au Chapitre 7. +le chapitre 5 et lorsque nous allons aborder l'espace de nom au chapitre 7. -Ce type de chaîne de caractères *peut* être mutable : +Ce type de chaîne de caractères *peut* être mutable : -Donc, quelle est la différence ici ? Pourquoi `String` peut être mutable, mais -que les chaînes pures ne peuvent pas l'être ? La différence est comment ces -deux types travaillent avec la mémoire. +Donc, quelle est la différence ici ? Pourquoi `String` peut être mutable, mais +pourquoi les chaînes de caractères pures ne peuvent pas l'être ? La différence +se trouve dans la façon dont ces deux types travaillent avec la mémoire. -### Mémoire et attribution +### Mémoire et affectation -Avec le type `String`, afin de permettre un texte mutable et qui peut -s'aggrandir, nous devons allouer une quantité de mémoire sur la Heap, inconnue -au moment de la compilation, pour stocker le contenu. Cela signifie que : +Avec le type `String`, pour nous permettre d'avoir un texte mutable et qui peut +s'agrandir, nous devons allouer une quantité de mémoire sur le tas, inconnue +au moment de la compilation, pour stocker le contenu. Cela signifie que : -* La mémoire doit être sollicitée auprès du système d'exploitation lors de +* La mémoire doit être demandée auprès du système d'exploitation lors de l'exécution. * Nous avons besoin d'un moyen de rendre cette mémoire au système - d'exploitation quand nous avons fini avec notre `String`. + d'exploitation lorsque nous aurons fini d'utiliser notre `String`. -Le premier point est fait par nous : quand nous appelons `String::from`, sa -définition demande la mémoire dont elle a besoin. C'est pratiquement toujours -le cas dans les langages de programmation. +Nous nous occupons de ce premier point : quand nous appelons `String::from`, son +implémentation demande la mémoire dont elle a besoin. C'est pratiquement +toujours ainsi dans la majorité des langages de programmation. - Cependant, le deuxième point est différent. Dans des langages avec un *ramasse-miettes*, le ramasse-miettes surveille et nettoie la mémoire qui n'est -plus utilisée, sans que nous, les développeurs, nous ayons à nous en -préoccuper. Sans un ramasse-miettes, c'est de la responsabilité du développeur -d'identifier quand la mémoire n'est plus utilisée et d'appeler du code pour -explicitement la libérer, comme nous l'avons fait pour la demander auparavant. -Historiquement, faire ceci correctement a toujours été une difficulté pour -développer. Si nous oublions de le faire, nous allons gaspiller de la mémoire. -Si nous le faisons trop tôt, nous allons avoir une variable incorrecte. Si nous -le faisons deux fois, c'est aussi un bogue. Nous avons besoin d'associer -exactement un `allocate` avec exactement un `free`. +plus utilisée, sans que nous n'ayons à nous en préoccuper. Sans un +ramasse-miettes, c'est de notre responsabilité d'identifier quand cette mémoire +n'est plus utilisée et d'appeler du code pour explicitement la libérer, comme +nous l'avons fait pour la demander auparavant. Historiquement, faire ceci +correctement a toujours été une difficulté pour développer. Si nous oublions de +le faire, nous allons gaspiller de la mémoire. Si nous le faisons trop tôt, nous +allons avoir une variable invalide. Si nous le faisons deux fois, cela produit +aussi un bogue. Nous avons besoin d'associer exactement un `allocate` avec +exactement un `free`. -Rust prends un chemin différent : la mémoire est automatiquement libérée dès +Rust prend un chemin différent : la mémoire est automatiquement libérée dès que la variable qui la possède sort de la portée. Voici une version de notre -exemple de portée de l'entrée 4-1 qui utilise un `String` plutôt qu'une chaîne -de caractères pure : +exemple de portée de l'encart 4-1 qui utilise un `String` plutôt qu'une chaîne +de caractères pure : -Il y a un cas naturel auquel nous devons rendre la mémoire de notre `String` au -système d'exploitation : quand `s` sort de la portée. Quand une variable sort -de la portée, Rust utilise une fonction spéciale pour nous. Cette fonction -s'appelle `drop`, et ceci que l'auteur du `String` peut le mettre dans le code -pour libérer la mémoire. Rust utilise automatiquement `drop` à l'accolade -fermante `}`. +Ceci est un cas naturel pour lequel nous devons rendre la mémoire de notre +`String` au système d'exploitation : quand `s` sort de la portée. Quand une +variable sort de la portée, Rust utilise une fonction spéciale pour nous. Cette +fonction s'appelle `drop`, et c'est dans celle-ci que l'auteur du `String` a pu +mettre le code pour libérer la mémoire. Rust appelle automatiquement `drop` à +l'accolade fermante `}`. -> Note : dans du C++, cette façon de libérer des ressources à la fin de la -> durée de vie d'un objet est parfois appelé *Resource Acquisition Is -> Initialization (RAII)*. La fonction `drop` de Rust vous sera familière si -> vous avez déjà utilisé des fonctions de RAII. +> Remarque : dans du C++, cette façon de libérer des ressources à la fin de la +> durée de vie d'un élément est parfois appelé *l'acquisition d'une ressource +> est une initialisation (RAII)*. La fonction `drop` de Rust vous sera familière +> si vous avez déjà utilisé une configuration en RAII. Cette façon de faire a un impact profond sur la façon dont le code de Rust est -écrit. Cela peut sembler simple ici, mais le comportement du code peut être -inattendu dans des situations plus compliquées quand nous voulons avoir -plusieurs variables avec des données que nous avons allouées sur la Heap. +écrit. Cela peut sembler simple dans notre cas, mais le comportement du code +peut être surprenant dans des situations plus compliquées lorsque nous voulons +avoir plusieurs variables avec des données que nous avons affecté sur le tas. Examinons une de ces situations dès à présent. -#### Les interactions entre les variables et les données : les déplacements +#### Les interactions entre les variables et les données : les déplacements Plusieurs variables peuvent interagir avec les mêmes données de différentes -manières avec Rust. Regardons un exemple avec un entier dans l'entrée 4-2 : +manières avec Rust. Regardons un exemple avec un entier dans l'encart 4-2 : ```rust let x = 5; @@ -607,8 +607,8 @@ let y = x; to `y` --> -Entrée 4-2 : assigner la valeur entière de la variable -`x` à la `y` +Encart 4-2 : assigner l'entier de la variable `x` à `y` + -Nous pouvons deviner ce qui va probablement se passer grâce à notre expérience -avec d'autres langages : “Assigner la valeur `5` à `x`; ensuite faire une copie -de la valeur de `x` et l'assigner à `y`.” Nous avons maintenant deux variables, -`x` et `y`, et toutes les deux sont égales à `5`. C'est effectivement ce qui se -passe, car les entiers sont des valeurs simples avec une taille connue et -fixée, et ces deux valeurs `5` sont stockées sur la Stack. +Nous pouvons probablement deviner ce qui va se passer : “Assigner la valeur `5` +à `x`; ensuite faire une copie de cette valeur de `x` et l'assigner à `y`.” Nous +avons maintenant deux variables, `x` et `y`, et chacune vaut `5`. C'est +effectivement ce qui se passe, car les entiers sont des valeurs simples avec une +taille connue et fixée, et ces deux valeurs `5` sont stockées sur la pile. -Maintenant, regardons une nouvelle version avec `String` : +Maintenant, essayons une nouvelle version avec `String` : ```rust let s1 = String::from("hello"); @@ -643,8 +642,8 @@ value in `s1` and bind it to `s2`. But this isn’t quite what happens. --> Cela ressemble beaucoup au code précédent, donc nous allons supposer que cela -fonctionne pareil que précédemment : ainsi, la seconde ligne va faire une copie -de la valeur dans `s1` et l'assigner à `s2`. Mais ce n'est pas tout à fait ce +fonctionne pareil que précédemment : ainsi, la seconde ligne va faire une copie +de la valeur de `s1` et l'assigner à `s2`. Mais ce n'est pas tout à fait ce qu'il se passe. -Pour expliquer cela plus précisément, regardons à quoi ressemble `String` avec -l'illustration 4-1. Un `String` est constitué de trois éléments, présentes sur -la gauche : un pointeur vers la mémoire qui contient le contenu de la chaîne -de caractères, une taille, et une capacité. Ces données sont stockées sur la -Stack. Sur la droite est la mémoire sur la Heap qui contient les données. +Regardons l'illustration 4-1 pour découvrir ce qui arrive à `String` sous le +capot. Un `String` est constitué de trois éléments, présents sur la gauche : un +pointeur vers la mémoire qui contient le contenu de la chaîne de caractères, une +taille, et une capacité. Ce groupe de données est stocké sur la pile. A droite, +nous avons la mémoire sur le tas qui contient les données. String in memory @@ -668,7 +667,7 @@ Stack. Sur la droite est la mémoire sur la Heap qui contient les données. holding the value `"hello"` bound to `s1` --> -Illustration 4-1 : représentation d'un `String` dans la +Illustration 4-1 : représentation d'un `String` dans la mémoire qui contient la valeur `"hello"` assignée à `s1`. La taille est combien de mémoire, en octets, le contenu du `String` utilise -actuellement. La capacité est la quantité totale de mémoire, en octets, que +actuellement. La capacité est la quantité totale de mémoire, en octets, que le `String` a reçu du système d'exploitation. La différence entre la taille et la -capacité est importante, mais pas dans ce contexte, donc pour l'instant, ce -n'est pas grave de mettre de côté la capacité. +capacité est importante, mais pas pour notre exemple, donc pour l'instant, ce +n'est pas grave d'ignorer la capacité. Quand nous assignons `s1` à `s2`, les données de `String` sont copiées, ce qui -veut dire que nous copions le pointeur, la taille, et la capacité qu'il y a sur -la Stack. Mais nous ne copions pas les données sur la Heap dont fait référence -le pointeur. Autrement dit, la représentation des données dans la mémoire -ressemble à l'illustration 4-2. +veut dire que nous copions le pointeur, la taille, et la capacité qui sont +stockés sur la pile. Nous ne copions pas les données stockées sur le tas sur +lequel le pointeur se réfère. Autrement dit, la représentation des données dans +la mémoire ressemble à l'illustration 4-2. s1 and s2 pointing to the same value @@ -705,8 +704,9 @@ ressemble à l'illustration 4-2. that has a copy of the pointer, length, and capacity of `s1` --> -Illustration 4-2 : représentation dans la mémoire de la -variable `s2` qui est une copie du pointeur, taille et capacité de `s1` +Illustration 4-2 : représentation dans la mémoire de la +variable `s2` qui est une copie du pointeur, de la taille et de la capacité de +`s1` -La représentation *n'est pas* comme l'illustration 4-3, qui serait la mémoire -si Rust avait aussi copié les données sur la Heap. Si Rust fait cela, -l'opération `s2 = s1` pourrait potentiellement être coûteuse en termes de -performances d'exécution si les données sur la Heap étaient grosses. +Cette représentation *n'est pas* comme l'illustration 4-3, qui serait la mémoire +si Rust avait aussi copié les données sur le tas. Si Rust faisait ceci, +l'opération `s2 = s1` pourrait potentiellement être très coûteuse en termes de +performances d'exécution si les données sur le tas étaient volumineuses. s1 and s2 to two places @@ -727,8 +727,8 @@ performances d'exécution si les données sur la Heap étaient grosses. do if Rust copied the heap data as well --> -Illustration 4-3 : une autre possibilité de ce que -pourrait faire `s2 = s1` si Rust copiait aussi les données sur la Heap +Illustration 4-3 : une autre possibilité de ce que +pourrait faire `s2 = s1` si Rust copiait aussi les données du tas -Auparavant, nous avons que quand une variable sort de la portée, Rust appelait -automatiquement la fonction `drop` et nettoyait la mémoire sur la Heap -concernant cette variable. Mais l'illustration 4-2 montre que les deux -pointeurs de données pointaient au même endroit. C'est un problème : quand +Précédemment, nous avons dit que quand une variable sort de la portée, Rust +appelait automatiquement la fonction `drop` et nettoyait la mémoire sur le tas +utilisé par cette variable. Mais l'illustration 4-2 montre que les deux +pointeurs de données pointaient au même endroit. C'est un problème : quand `s2` et `s1` sortent de la portée, elles vont essayer toutes les deux de libérer la même mémoire. C'est ce qu'on appelle une erreur de *double libération* et c'est un des bogues de sécurité de mémoire que nous avons mentionné précédemment. Libérer la mémoire deux fois peut mener à des -corruptions de mémoire, qui peut potentiellement mener à des vulnérabilités +corruptions de mémoire, ce qui peut potentiellement mener à des vulnérabilités de sécurité. -Pour garantir la sécurité de la mémoire, il y a un autre détail en plus qui se -passe dans cette situation avec Rust. Plutôt qu'essayer de copier la mémoire -allouée, Rust considère que `s1` n'est plus en vigueur et du fait, Rust n'a pas -besoin de libérer quoi que ce soit lorsque `s1` sort de la portée. Regardes ce +Pour garantir la sécurité de la mémoire, il y a un autre petit détail qui se +produit dans cette situation avec Rust. Plutôt qu'essayer de copier la mémoire +affectée, Rust considère que `s1` n'est plus en vigueur et du fait, Rust n'a pas +besoin de libérer quoi que ce soit lorsque `s1` sort de la portée. Regardez ce qu'il se passe quand vous essayez d'utiliser `s1` après que `s2` soit créé, -cela ne va pas fonctionner : +cela ne va pas fonctionner : ```rust,ignore,does_not_compile let s1 = String::from("hello"); @@ -778,8 +778,8 @@ You’ll get an error like this because Rust prevents you from using the invalidated reference: --> -Vous allez avoir une erreur comme celle-ci, car Rust vous défends d'utiliser la -référence qui n'est plus en vigueur : +Vous allez avoir une erreur comme celle-ci, car Rust vous défend d'utiliser la +référence qui n'est plus en vigueur : ```text error[E0382]: use of moved value: `s1` @@ -804,13 +804,13 @@ shallow copy, it’s known as a *move*. In this example, we would say that `s1` was *moved* into `s2`. So what actually happens is shown in Figure 4-4. --> -Si vous avez déjà entendu parler de “copie de surface” et de “copie en +Si vous avez déjà entendu parler de “copie superficielle” et de “copie en profondeur” en utilisant d'autres langages, l'idée de copier le pointeur, la taille et la capacité sans copier les données peut vous faire penser à de la -copie de surface. Mais parce que Rust invalide aussi la première variable, au -lieu d'appeler cela une copie de surface, on appelle cela un *déplacement*. -Ici nous pourrions lire ainsi en disant que `s1` a été *déplacé* dans `s2`. -Donc ce qui se passe réellement est montré dans l'illustration 4-4. +copie superficielle. Mais comme Rust neutralise aussi la première variable, au +lieu d'appeler cela une copie superficielle, on appelle cela un *déplacement*. +Ici nous pourrions dire que `s1` a été *déplacé* dans `s2`. Donc voici ce qui se +passe réellement dans l'illustration 4-4. s1 moved to s2 @@ -819,15 +819,15 @@ Donc ce qui se passe réellement est montré dans l'illustration 4-4. invalidated --> -Illustration 4-4 : Représentation de la mémoire après que -`s1` a été invalidé +Illustration 4-4 : représentation de la mémoire après que +`s1` ai été neutralisée -Cela résout notre problème ! Avec seulement `s2` en vigueur, quand elle +Cela résout notre problème ! Avec seulement `s2` en vigueur, quand elle sortira de la portée, elle seule va libérer la mémoire, et c'est tout. -De plus, cela signifie qu'il y a eu un choix de conception : Rust ne va jamais +De plus, cela signifie qu'il y a eu un choix de conception : Rust ne va jamais créer des copies “profondes” de vos données. Par conséquent, toute copie *automatique* peut être considérée comme peu coûteuse en termes de performances d'exécution. @@ -845,7 +845,7 @@ d'exécution. #### Ways Variables and Data Interact: Clone --> -#### Les interactions entre les variables et les données : le clonage +#### Les interactions entre les variables et les données : le clonage -Si nous *voulons* faire une copie profonde des données sur la Heap d'un -`String`, et pas seulement des données sur la Stack, nous pouvons utiliser une -méthode courante qui s'appelle `clone`. Nous allons aborderons la syntaxe des -méthodes dans le chapitre 5, mais parce que les méthodes sont un outil courant -dans de nombreux langages, vous les avez probablement utilisé auparavant. +Si nous *voulons* faire une copie profonde des données sur le tas d'un `String`, +et non pas seulement des données sur la pile, nous pouvons utiliser une méthode +commune qui s'appelle `clone`. Nous allons aborderons la syntaxe des méthodes +dans le chapitre 5, mais comme les méthodes sont des outils courants dans de +nombreux langages, vous les avez probablement utilisé auparavant. -Voici un exemple d'utilisation de la méthode `clone` : +Voici un exemple d'utilisation de la méthode `clone` : ```rust let s1 = String::from("hello"); @@ -879,8 +879,7 @@ where the heap data *does* get copied. --> Cela fonctionne très bien et c'est ainsi que vous pouvez reproduire le -comportement décrit dans l'illustration 4-3, dans les données de la Heap sont -copiées. +comportement décrit dans l'illustration 4-3, où les données du tas sont copiées. -Quand vous voyez un appel à `clone`, vous savez que du code arbitraire est -exécuté et que ce code peu coûteux. C'est un indicateur visuel qu'il se passe -quelque chose de différent. +Quand vous voyez un appel à `clone`, vous savez que du code abstrait est exécuté +et que ce code peu coûteux. C'est un indicateur visuel qu'il se passe quelque +chose de différent. -#### Données seulement sur la Stack : les copier +#### Données uniquement sur la pile : les copier Il y a une autre faille dont on n'a pas encore parlé. Le code suivant utilise -des entiers, dont une partie a déjà été montré dans l'entrée 4-2, il fonctionne -et est correct : +des entiers, comme cela a déjà été montré dans l'encart 4-2, il fonctionne et +est correct : ```rust let x = 5; @@ -919,7 +918,7 @@ But this code seems to contradict what we just learned: we don’t have a call t `clone`, but `x` is still valid and wasn’t moved into `y`. --> -Mais ce code semble contredire ce que nous venons d'apprendre : nous n'avons +Mais ce code semble contredire ce que nous venons d'apprendre : nous n'avons pas appelé un `clone`, mais `x` est toujours en vigueur et n'a pas été déplacé dans `y`. @@ -932,13 +931,13 @@ between deep and shallow copying here, so calling `clone` wouldn’t do anything different from the usual shallow copying and we can leave it out. --> -La raison est que ces types tels que les entiers ont une taille connue au -moment de la compilation et sont entièrement stockées sur la Stack, donc copie -les valeurs actuelles, ce qui est rapide à faire. Cela signifie qu'il n'y a pas -de raison que nous voudrions empêcher `x` d'être toujours en vigueur après -avoir créé la variable `y`. En d'autres termes, ici il n'y a pas de différence -entre la copie en surface et profonde, donc appeler `clone` ne ferait rien de -différent que la copie en surface habituelle et nous pouvons l'exclure. +La raison est que les types comme les entiers ont une taille connue au moment de +la compilation et sont entièrement stockées sur la pile, donc la copie de la +valeur actuelle est rapide à faire. Cela signifie qu'il n'y a pas de raison que +nous voudrions neutraliser `x` après avoir créé la variable `y`. En d'autres +termes, il n'y a pas ici de différence entre la copie superficielle et profonde, +donc appeler `clone` ne ferait rien de différent que la copie superficielle +classe et nous n'avons pas besoin de l'utiliser. -Rust a une annotation spéciale appelée le trait `Copy` que nous pouvons -utiliser sur des types comme les entiers qui sont stockés sur la Stack (nous -verrons les traits dans le chapitre 10). Si un type a le trait `Copy`, -l'ancienne variable est toujours utilisable après son affectation. Rust ne pas -nous autoriser à annoter type avec le trait `Copy` si ce type, ou un de ses -éléments, a implémenté le trait `Drop`. Si ce type a besoin que quelque chose -de spécial se passe quand la valeur sort de la portée et que nous ajoutons -l'annotation `Copy` sur ce type, nous allons avoir une erreur au moment de la -compilation. Pour en savoir plus sur comment ajouter l'annotation `Copy` sur -votre type, reférez-vous à l'annexe C sur les traits dérivés. +Rust a une annotation spéciale appelée le trait `Copy` que nous pouvons utiliser +sur des types comme les entiers qui sont stockés sur la pile (nous verrons les +traits dans le chapitre 10). Si un type a le trait `Copy`, l'ancienne variable +sera toujours utilisable après son affectation. Rust ne va pas nous autoriser à +annoter un type avec le trait `Copy` si ce type, ou un de ses éléments, a +implémenté le trait `Drop`. Si ce type a besoin que quelque chose de spécial se +passe quand la valeur sort de la portée et que nous ajoutons l'annotation `Copy` +sur ce type, nous allons avoir une erreur au moment de la compilation. Pour en +savoir comment ajouter l'annotation `Copy` sur votre type, reférez-vous à +l'annexe C. - -Donc, quels sont les types qui ont `Copy` ? Vous pouvez regarder dans la -documentation pour un type donné pour vous en assurer, mais de manière -générale, tout groupe de simple scalaire peut être `Copy`, (TODO) and nothing that requires allocation or is some form of resource is `Copy`. -Voici quelques types qui sont `Copy` : +Donc, quels sont les types qui ont `Copy` ? Vous pouvez regarder dans la +documentation pour un type donné pour vous en assurer, mais de manière générale, +tout groupe de valeur scalaire peut être `Copy`, et tout ce qui ne nécessite pas +d'affectation de mémoire ou tout autre forme quelconque de ressource est `Copy`. +Voici quelques types qui sont `Copy` : -### L'appropriation et les fonctions +### La possession et les fonctions -Nom du fichier : src/main.rs +Fichier : src/main.rs -Entrée 4-3 : les fonctions avec les appartenances et les +Encart 4-3 : les fonctions avec les possessions et les portées qui sont commentées -Si nous essayons d'utiliser `s` après l'appel à `takes_ownership`, Rust va -lever et retourner une erreur au moment de la compilation. Ces vérifications -statiques nous protègent des erreurs. Essayez d'ajouter du code au `main` qui -utilise `s` et `x` pour voir quand vous pouvez les utiliser et quand les règles -de l'appartenance vous empêchent de le faire. +Si on essayait d'utiliser `s` après l'appel à `prendre_possession`, Rust va +déclencher une erreur au moment de la compilation. Ces vérifications statiques +nous protègent des erreurs. Essayez d'ajouter du code au `main` qui utilise `s` +et `x` pour découvrir lorsque vous pouvez les utiliser et lorsque les règles de +la possession vous empêchent de le faire. -### Les valeurs de retour et la portée +### Les valeurs de retour et les portées -Renvoyer les valeurs peut aussi transférer leur appartenance. Voici un exemple -avec des annotations similaires à celles de l'entrée 4-3 : +Renvoyer les valeurs peut aussi transférer leur possession. L'encart 4-4 est un +exemple avec des annotations similaires à celles de l'encart 4-3 : -Nom du fichier : src/main.rs +Fichier : src/main.rs + +Encart 4-4 : transferts de possessions des valeurs de +retour -L'appartenance d'une variable suit toujours le même processus à chaque fois : -assigner une valeur à une variable la déplace. Quand une variable qui contient -des données sur la Heap sort de la portée, la valeur va être nettoyée de la -mémoire avec `drop` à moins que la donnée aie été déplacée pour appartenir à -une autre variable. +La possession d'une variable suit toujours le même schéma à chaque fois : +assigner une valeur à une autre variable la déplace. Quand une variable qui +contient des données sur le tas sort de la portée, la valeur va être nettoyée +avec `drop` à moins que la donnée ait été déplacée pour être possédée par une +autre variable. -Il est un peu fastidieux de prendre l'appartenance puis ensuite de retourner -l'appartenance avec chaque fonction. Et qu'est ce qu'il se passe si nous -voulons qu'une fonction utilise une valeur, mais ne se l'approprie pas ? C'est +Il est un peu fastidieux de prendre la possession puis ensuite de retourner la +possession avec chaque fonction. Et qu'est ce qu'il se passe si nous voulons +qu'une fonction utilise une valeur, mais n'en prenne pas possession ? C'est assez pénible que tout ce que nous envoyons doit être retourné si nous voulons -l'utiliser à nouveau, en plus de toutes les données qui découlent de -l'exécution de la fonction que nous voulons aussi récupérer. +l'utiliser à nouveau, en plus de toutes les données qui découlent de l'exécution +de la fonction que nous voulons aussi récupérer. -Il est possible de retourner plusieurs valeurs en utilisant un tuple, comme -ceci : +Il est possible de retourner plusieurs valeurs à l'aide d'un tuple, comme ceci : -Nom du fichier : src/main.rs +Fichier : src/main.rs - ```rust fn main() { let s1 = String::from("hello"); - let (s2, len) = calculate_length(s1); + let (s2, len) = calculer_taille(s1); - println!("The length of '{}' is {}.", s2, len); + println!("La taille de '{}' est {}.", s2, len); } -fn calculate_length(s: String) -> (String, usize) { +fn calculer_taille(s: String) -> (String, usize) { let length = s.len(); // len() renvoie le nombre de caractères d'un String. (s, length) } ``` + + +Encart 4-5 : retourner la possession des paramètres -Mais c'est trop de cérémonies et beaucoup de travail pour un principe qui -devrait être courant. Heureusement pour nous, Rust a une fonctionnalité pour -ce principe, et c'est ce qu'on appelle les *références*. +Mais c'est trop cérémonieux et beaucoup de travail pour un principe qui devrait +être banal. Heureusement pour nous, Rust a une fonctionnalité pour ce principe, +c'est ce qu'on appelle les *références*. + + +[data-types]: ch03-02-data-types.html#les-types-de-données diff --git a/FRENCH/src/translation-terms.md b/FRENCH/src/translation-terms.md index d3146acecf..552699b2c2 100644 --- a/FRENCH/src/translation-terms.md +++ b/FRENCH/src/translation-terms.md @@ -6,13 +6,17 @@ français. | Anglais | Français | Remarques | | ------- | ------ | ------ | | ahead-of-time compilation | compilation anticipée | sigle : AOT | +| allocation | affectation | - | +| annotate | annoter | - | | Application Programming Interface (API) | interface de programmation applicative (API) | - | +| assign | assigner | - | | argument | argument / paramètre | - | | arm | branche | dans une expression `match` | | artifact | artéfact | - | | associated function | fonction associée | - | | binary crate | crate binaire | s'utilise au féminin | | *n*-bit number | nombre encodé sur *n* bits | - | +| blob | blob | - | | boolean | booléen | - | | borrow | emprunt(er) | - | | bug | bogue | - | @@ -37,16 +41,19 @@ français. | data representation | modèle de données | - | | debug | déboguer | - | | debugging | débogage | - | +| deep copy | copie en profondeur | - | | dependency | dépendance | - | | destructure | déstructurer | - | | DevOps | DevOps | - | | dot notation | la notation avec un point | - | +| double free | double libération | - | | enum | énumération | - | | enumeration | énumération | - | | enum’s variant | variante d'énumération | - | | exploit | faille | - | | expression | expression | - | | field | champ | d'une structure | +| Figure | Illustration | - | | flag | drapeau | pour les programmes en ligne de commande | | function | fonction | - | | generics | génériques / généricité | - | @@ -54,12 +61,14 @@ français. | handle | référence | - | | hash | hash / relatif au hachage | - | | hash map | table de hachage | - | +| heap | (le) tas | - | | Hello, world! | Hello, world! | - | | high-level | haut niveau | - | | identifier | identificateur | - | | instance | instance | - | | instantiate | instancier | créer une instance | | Integrated Development Environment (IDE) | environnement de développement intégré (IDE) | - | +| invalidate | neutraliser | - | | IOT | internet des objets (IOT) | - | | immutable | immuable | - | | iterator | itérateur | - | @@ -78,11 +87,15 @@ français. | memory management | gestion de mémoire | - | | method | méthode | - | | module | module | - | +| move | déplacement | - | | mutability | mutabilité | - | | mutable | mutable | modifiable | +| namespace | espace de nom | - | +| namespacing | l'espace de nom | - | | Note | Remarque | - | | numerical characters | chiffres | - | | operating system | système d'exploitation | - | +| owner | propriétaire | - | | ownership | possession | - | | package manager | système de gestion de paquets | - | | panic | panique(r) | - | @@ -91,9 +104,12 @@ français. | pattern | motif | - | | pattern-matching | filtrage par motif | - | | placeholder | espace réservé | `{}` pour `fmt` | +| pointer | pointeur | - | +| popping off the stack | retirer de la pile | - | | prelude | étape préliminaire | - | | procedural macro | macro procédurale | - | | project chapter | chapitre de projet | - | +| pushing onto the stack | déposer sur la pile | - | | raw identifier | identificateur brut | - | | README | README | - | | refactoring | remaniement | - | @@ -101,13 +117,16 @@ français. | registry | registre | - | | regression | régression | - | | reproducible build | compilation reproductible | - | +| Resource Acquisition Is Initialization (RAII) | l'acquisition d'une ressource est une initialisation (RAII) | - | | run | exécuter | pour les programmes | | Rustacean | Rustacé | - | | section header | entête de section | - | | semantic version | version sémantique | - | +| scope | portée | - | | script | script | - | | shadow | masquer | remplacer une variable par une autre de même nom | | shadowing | masquage | - | +| shallow copy | copie superficielle | - | | shell | terminal / invite de commande | - | | shorthand | abréviation | - | | sidebar | barre latérale | - | @@ -116,6 +135,7 @@ français. | smart pointer | pointeur intelligent | - | | snip | code inchangé masqué ici | dans un encart | | space | espace | ce mot est féminin quand on parle du caractère typographique | +| stack | (la) pile | - | | standard | standard *(adj. inv.)* / norme *(n.f.)* | - | | standard error | erreur standard | - | | standard input | entrée standard | - | @@ -123,6 +143,7 @@ français. | standard output | sortie standard | - | | statement | instruction | - | | string | chaîne de caractères | - | +| string literal | chaîne de caractères pure | - | | struct | structure | - | | submodule | sous-module | - | | systems concept | notion système | - | From 1d0748a550e050d77fa4a532bc3e35bc40ec7e44 Mon Sep 17 00:00:00 2001 From: Jimskapt Date: Tue, 20 Aug 2019 07:10:11 +0200 Subject: [PATCH 048/117] :twisted_rightwards_arrows: Merging translation of ch04-02 by @Jimskapt From https://github.com/quadrifoglio/rust-book-fr/blob/fr-ch04/second-edition/src/ch04-02-references-and-borrowing.md --- FRENCH/src/SUMMARY.md | 2 + .../src/ch04-02-references-and-borrowing.md | 852 ++++++++++++++++++ 2 files changed, 854 insertions(+) create mode 100644 FRENCH/src/ch04-02-references-and-borrowing.md diff --git a/FRENCH/src/SUMMARY.md b/FRENCH/src/SUMMARY.md index 45cc984e60..875c2ec5c7 100644 --- a/FRENCH/src/SUMMARY.md +++ b/FRENCH/src/SUMMARY.md @@ -10,3 +10,5 @@ - [Installation](ch01-01-installation.md) - [Hello, world!](ch01-02-hello-world.md) - [Hello, Cargo!](ch01-03-hello-cargo.md) + +- [Les références et l'emprunt](ch04-02-references-and-borrowing.md) diff --git a/FRENCH/src/ch04-02-references-and-borrowing.md b/FRENCH/src/ch04-02-references-and-borrowing.md new file mode 100644 index 0000000000..97774963d4 --- /dev/null +++ b/FRENCH/src/ch04-02-references-and-borrowing.md @@ -0,0 +1,852 @@ + + +## Les références et l'emprunt + + + +Le problème avec le code du tuple à la fin de la section précédente c'est que +nous avons besoin de retourner le `String` au code appelant pour qu'il puisse +encore utiliser le `String` après l'appel à `calculate_length`, car +l'appartenance du `String` a été déplacée dans `calculate_length`. + + + +Ici vous allez définir et utiliser une fonction `calculate_length` qui prend +une *référence* à un objet en paramètre plutôt que de s'approprier la valeur : + + + +Nom du fichier : src/main.rs + + + +```rust +fn main() { + let s1 = String::from("hello"); + + let len = calculate_length(&s1); + + println!("The length of '{}' is {}.", s1, len); +} + +fn calculate_length(s: &String) -> usize { + s.len() +} +``` + + + +Premièrement, remarquez que tout le code avec le tuple dans la déclaration des +variables et dans le retour de la fonction a été enlevé. Ensuite, on peut +constater que nous envoyons `&s1` dans `calculate_length`, et que dans sa +définition, nous utilisons `&String` plutôt que `String`. + + + +Ces esperluettes sont des *références*, et elles permettent de vous référer à +une valeur sans se l'approprier. L'illustration 4-5 nous montre cela dans un +diagramme. + +&String s pointing at String s1 + + + +Illustration 4-5 : `&String s` pointe sur `String s1` + + + +> Note : l'opposé du référencement en utilisant `&` est le *déréférencement*, +> qui est effectué par l'opérateur de déréférencement, `*`. Nous allons voir +> quelques utilisations de l'opérateur de déréférencement dans le Chapitre 8 et +> nous discuterons des détails du déréférencement dans le Chapitre 15. + + + +Regardons de plus près les appels de fonction utilisées : + + + +```rust +# fn calculate_length(s: &String) -> usize { +# s.len() +# } +let s1 = String::from("hello"); + +let len = calculate_length(&s1); +``` + + + +La syntaxe `&s1` nous permet de créer une référence qui se *réfère* à la valeur +de `s1` mais ne s'approprie pas. Par ce qu'elle ne se l'approprie pas, la +valeur qu'elle désigne ne sera pas libérée quand la référence sortira de la +portée. + + + +De la même manière, la signature de la fonction utilise `&` pour indiquer que +le type de paramètre `s` est une référence. Ajoutons quelques commentaires +explicatifs : + + + +```rust +fn calculate_length(s: &String) -> usize { // s est une référence à un String + s.len() +} // Ici, s sort de la porté. Mais comme elle ne s'approprie pas ce dont elle + // fait référence, il ne se passe rien. +``` + + + +La portée dans laquelle la variable `s` est en vigueur est la même que toute +portée de paramètre de fonction, mais nous ne libérons pas ce sur quoi cette +référence pointe quand elle sort de la portée, car nous ne nous l'avons pas +approprié. Les fonctions qui ont des références en paramètres au lieu des +valeurs effectives veulent dire que nous n'avons pas besoin de retourner les +valeurs pour rendre leur appartenance, puis nous n'avons jamais eu +l'appartenance. + + + +Quand nous avons des références dans les paramètres d'une fonction, nous +appelons cela *l'emprunt*. Comme dans la vie réelle, quand un objet appartient +à quelqu'un, vous pouvez lui emprunter. Quand vous avez fini, vous devez lui +rendre. + + + +Donc qu'est-ce qui se passe si nous essayons de modifier quelque chose que nous +empruntons ? Essayez le code dans l'entrée 4-4. Spoiler : cela ne fonctionne +pas ! + + + +Nom du fichier : src/main.rs + + + +```rust,ignore +fn main() { + let s = String::from("hello"); + + change(&s); +} + +fn change(some_string: &String) { + some_string.push_str(", world"); +} +``` + + + +Entrée 4-4: tentative de modification d'une valeur +empruntée. + + + +Voici l'erreur : + + + + +```text +error[E0596]: cannot borrow immutable borrowed content `*some_string` as mutable + --> error.rs:8:5 + | +7 | fn change(some_string: &String) { + | ------- use `&mut String` here to make mutable +8 | some_string.push_str(", world"); + | ^^^^^^^^^^^ cannot borrow as mutable +``` + + + +Comme les variables sont immuables par défaut, les références le sont aussi. +Nous ne sommes pas autorisés à modifier une chose quand nous avons une +référence vers elle. + + + +### Les références modifiables + + + +Nous pouvons résoudre l'erreur dans le code de l'entrée 4-4 avec une petite +modification : + + + +Nom de fichier : src/main.rs + + + +```rust +fn main() { + let mut s = String::from("hello"); + + change(&mut s); +} + +fn change(some_string: &mut String) { + some_string.push_str(", world"); +} +``` + + + +Premièrement, nous devons modifier `s` pour être `mut`. Ensuite, nous devons +créer une référence modifiable avec `&mut s` et prendre une référence +modifiable avec `some_string: &mut String`. + + + +Mais les références modifiables ont une grosse restriction : vous ne pouvez +avoir qu'une seule référence modifiable pour un article de donnée précis dans +une portée précise. Le code suivant va échouer : + + + +Nom de fichier : src/main.rs + + + +```rust,ignore +let mut s = String::from("hello"); + +let r1 = &mut s; +let r2 = &mut s; +``` + + + +Voici l'erreur : + + + +```text +error[E0499]: cannot borrow `s` as mutable more than once at a time + --> borrow_twice.rs:5:19 + | +4 | let r1 = &mut s; + | - first mutable borrow occurs here +5 | let r2 = &mut s; + | ^ second mutable borrow occurs here +6 | } + | - first borrow ends here +``` + + + +Cette restriction autorise les mutations, mais de façon très contrôlée. C'est +ce avec quoi les nouveaux Rustacéens ont du mal, car la plupart des langages +vous permettent de modifier les données quand vous voulez. L'avantage de cette +restriction c'est que Rust peut empêcher la concurrence des données au moment +de la compilation. + + + +La *concurrence des données* ressemble à une concurrence critique et se produit +quand ces trois facteurs se combinent : + + + +1. Un ou plusieurs pointeurs accèdent à la même donnée au même moment. +2. Au moins un des pointeurs est utilisé pour écrire dans les données. +3. On n'utilise pas de processus pour synchroniser l'accès aux données. + + + +La concurrence des données provoque des comportements inexpliqués et il peut +alors être difficile de diagnostiquer et résoudre le problème lorsque vous +essayez de les traquer au moment de l'exécution; Rust évite que ce problème +arrive parcequ'il ne va même pas compiler le code avec de la concurrence de +données ! + + + +Comme toujours, nous pouvons utiliser des accolades pour créer une nouvelle +portée, pour nous permettre d'avoir plusieurs références modifiables, mais pas +*simultanées* : + + + +```rust +let mut s = String::from("hello"); + +{ + let r1 = &mut s; + +} // r1 sort de la portée ici, donc nous pouvons faire une nouvelle référence + // sans problèmes. + +let r2 = &mut s; +``` + + + +Une règle similaire existe pour mélanger les références immuables et +modifiables. Ce code va mener à une erreur : + + + +```rust,ignore +let mut s = String::from("hello"); + +let r1 = &s; // sans problème +let r2 = &s; // sans problème +let r3 = &mut s; // GROS PROBLEME +``` + + + +Voici l'erreur : + + + +```text +error[E0502]: cannot borrow `s` as mutable because it is also borrowed as +immutable + --> borrow_thrice.rs:6:19 + | +4 | let r1 = &s; // no problem + | - immutable borrow occurs here +5 | let r2 = &s; // no problem +6 | let r3 = &mut s; // BIG PROBLEM + | ^ mutable borrow occurs here +7 | } + | - immutable borrow ends here +``` + + + +Ouah ! Nous ne pouvons pas *non plus* avoir une référence modifiable si nous en +avons une d'immuable. Les utilisateurs d'une référence immuable ne s'attendent +pas à ce que se valeur change soudainement ! Cependant, l'utilisation de +plusieurs références immuables ne pose pas de problème, car personne de ceux +qui lisent uniquement la donnée n'a la possibilité de modifier la lecture de la +donnée par les autres. + + + +Même si ces erreurs peuvent parfois être frustrantes, souvenez-vous que le +compilateur de Rust nous fait remarquer un futur bogue avant l'heure (au moment +de la compilation plutôt que lors de l'exécution) et vous montre où est +exactement le problème plutôt que vous ayez à traquer pourquoi *des fois* vos +données ne correspondent pas à ce que vous pensiez qu'elles étaient. + + + + + +```rust,edition2018,ignore +let mut s = String::from("hello"); + +let r1 = &s; // no problem +let r2 = &s; // no problem +println!("{} and {}", r1, r2); +// r1 and r2 are no longer used after this point + +let r3 = &mut s; // no problem +println!("{}", r3); +``` + + + +The scopes of the immutable references `r1` and `r2` end after the `println!` +where they are last used, which is before the mutable reference `r3` is +created. These scopes don’t overlap, so this code is allowed. + + + +Even though borrowing errors may be frustrating at times, remember that it’s +the Rust compiler pointing out a potential bug early (at compile time rather +than at runtime) and showing you exactly where the problem is. Then you don’t +have to track down why your data isn’t what you thought it was. + + + +### Références en suspension + + + +Avec les langages qui utilisent les pointeurs, c'est facile de créer par erreur +un *pointeur en suspension*, qui est un pointeur qui désigne un endroit dans la +mémoire qui a été donné par quelqu'un d'autre, en libérant une partie de la +mémoire, mais en conservant un pointeur vers cette mémoire. En revanche, dans +Rust, le compilateur garantie que les références ne seront jamais des +références en suspension : si nous avons une référence vers des données, le +compilateur va s'assurer que cette donnée ne vas pas sortir de la portée avant +que la référence vers cette donnée soit sortie. + + + +Essayons de créer une référence en suspension, que Rust va empêcher avec une +erreur au moment de la compilation : + + + +Nom du fichier : src/main.rs + + + +```rust,ignore +fn main() { + let reference_to_nothing = dangle(); +} + +fn dangle() -> &String { + let s = String::from("hello"); + + &s +} +``` + + + +Voici l'erreur : + + + +```text +error[E0106]: missing lifetime specifier + --> dangle.rs:5:16 + | +5 | fn dangle() -> &String { + | ^ expected lifetime parameter + | + = help: this function's return type contains a borrowed value, but there is + no value for it to be borrowed from + = help: consider giving it a 'static lifetime +``` + + + +Ce message d'erreur parle d'une fonctionnalité que nous n'avons pas encore vu : +les *durées de vie*. Nous allons voir plus en détail les durées de vie dans le +Chapitre 10. Mais, si vous mettez de côté les parties qui parlent de la durée +de vie, le message désigne l'élément de code qui pose problème : + + + +```text +this function's return type contains a borrowed value, but there is no value +for it to be borrowed from. +``` + + + +Regardons de plus près ce qui se passe à chaque étape de notre code `dangle` : + + + +Filename: src/main.rs + + + + +```rust,ignore +fn dangle() -> &String { // dangle returnes une référence vers un String + + let s = String::from("hello"); // s est un nouveau String + + &s // nous retournons une référence vers le String, s +} // Ici, s sort de la portée, et est libéré. Sa mémoire disparait. Danger ! +``` + + + +Parce que `s` est créé dans `dangle`, quand le code de `dangle` est terminé, +`s` va être désaloué. Mais nous avions essayé de renvoyer une référence vers +elle. Cela veut dire que cette référence va pointer vers un `String` invalide ! +Ce n'est pas bon. Rust ne nous laissera pas faire cela. + + + +Ici la solution est de renvoyer le `String` directement : + + + +```rust +fn no_dangle() -> String { + let s = String::from("hello"); + + s +} +``` + + + +Cela fonctionne sans problème. L'appartenance est déplacée, et rien n'est +désaloué. + + + +### Les règles de référencement + + + +Récapitulons ce que nous avons vu à propos des références : + + + +1. Vous pouvez avoir *un* des deux cas suivants, mais pas les deux en même +temps : + * Une référence modifiable. + * Un nombre illimité de références immuables. +2. Les références doivent toujours être en vigueur. + + + +A l'étape suivante, nous allons aborder un type différent de référence : les +slices. From 52ffe26726f784ab0720443a82441060add8b630 Mon Sep 17 00:00:00 2001 From: Jian Weihang Date: Wed, 21 Aug 2019 11:39:51 +0800 Subject: [PATCH 049/117] unit type value is also a value --- src/ch20-02-multithreaded.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ch20-02-multithreaded.md b/src/ch20-02-multithreaded.md index 2e64463486..e80b05e0ce 100644 --- a/src/ch20-02-multithreaded.md +++ b/src/ch20-02-multithreaded.md @@ -364,7 +364,7 @@ impl ThreadPool { ``` We still use the `()` after `FnOnce` because this `FnOnce` represents a closure -that takes no parameters and doesn’t return a value. Just like function +that takes no parameters and returns an unit type `()`. Just like function definitions, the return type can be omitted from the signature, but even if we have no parameters, we still need the parentheses. From 41f3f0040dce7cd3cdd5d12b357df25f0a393b86 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=ABl=20J=2E=20Pr=C3=A9sent?= <36854931+joeljpresent@users.noreply.github.com> Date: Wed, 21 Aug 2019 11:04:26 +0200 Subject: [PATCH 050/117] Proofread ch03-00 --- FRENCH/src/ch03-00-common-programming-concepts.md | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/FRENCH/src/ch03-00-common-programming-concepts.md b/FRENCH/src/ch03-00-common-programming-concepts.md index 0d07f9ce2c..1bef574849 100644 --- a/FRENCH/src/ch03-00-common-programming-concepts.md +++ b/FRENCH/src/ch03-00-common-programming-concepts.md @@ -14,9 +14,9 @@ around using these concepts. Ce chapitre explique des concepts qui apparaissent dans presque tous les langages de programmation, et la manière dont ils fonctionnent en Rust. De -nombreux langages sont basés sur des concepts communs. Dans ce chapitre, nous -n'allons présenter aucun concept spécifique à Rust, mais nous les appliquerons -à Rust et nous expliquerons les conventions qui leur sont liés. +nombreux langages sont basés sur des concepts communs. Les concepts présentés +dans ce chapitre ne sont pas spécifiques à Rust, mais nous les appliquerons +à Rust et nous expliquerons les conventions qui leur sont liées. -> #### Mot-clés +> #### Mots-clés > > Le langage Rust possède un ensemble de *mots-clés* qui ont été réservés pour > l'usage exclusif du langage, tout comme le font d'autres langages. Gardez à > l'esprit que vous ne pouvez pas utiliser ces mots pour des noms de variables > ou de fonctions. La plupart des mots-clés ont une signification spéciale, et > vous les utiliserez pour réaliser de différentes tâches dans vos programmes -> Rust; quelques-uns n'ont aucune fonctionnalité active pour le moment, mais ont -> été réservés pour être ajoutés plus tard à Rust. Vous pouvez trouver la liste -> de ces mots-clés dans l'Annexe A. +> Rust ; quelques-uns n'ont aucune fonctionnalité active pour le moment, mais +> ont été réservés pour être ajoutés plus tard à Rust. +> Vous pouvez trouver la liste de ces mots-clés dans l'annexe A. From 16bc2786d9623ce0dd2184bfd86323d88150397e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=ABl=20J=2E=20Pr=C3=A9sent?= <36854931+joeljpresent@users.noreply.github.com> Date: Thu, 22 Aug 2019 16:56:47 +0200 Subject: [PATCH 051/117] Translating ch05-00 in French --- FRENCH/src/ch05-00-structs.md | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) create mode 100644 FRENCH/src/ch05-00-structs.md diff --git a/FRENCH/src/ch05-00-structs.md b/FRENCH/src/ch05-00-structs.md new file mode 100644 index 0000000000..8942b6cfbf --- /dev/null +++ b/FRENCH/src/ch05-00-structs.md @@ -0,0 +1,29 @@ + + +# Utiliser les structures pour structurer des données apparentées + + + +Une *struct*, ou *structure*, est un type de données personnalisé qui vous +permet de nommer et de rassembler plusieurs valeurs apparentées qui forment +un groupe cohérent. +Si vous êtes familier avec un langage orienté objet, une structure est en +quelque sorte l'ensemble des attributs d'un objet. +Dans ce chapitre, nous comparerons les tuples avec les structures, montrerons +comment utiliser les structures et aborderons la définition des méthodes et des +fonctions associées pour spécifier le comportement associé aux données d'une +structure. +Les structures et les énumérations (traitées au chapitre 6) sont les fondements +de la création de nouveaux types au sein de votre programme pour tirer +pleinement parti des vérifications de types effectuées par Rust à la +compilation. From d290e1ca97d3aafbd3786d81f523de7c47053587 Mon Sep 17 00:00:00 2001 From: Thomas Ramirez Date: Fri, 23 Aug 2019 17:28:52 +0200 Subject: [PATCH 052/117] :typo: Changing translation of the function `calculer_longueur` to `calculer_longueur` --- FRENCH/src/ch04-01-what-is-ownership.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/FRENCH/src/ch04-01-what-is-ownership.md b/FRENCH/src/ch04-01-what-is-ownership.md index e56962bc9b..1d403db284 100644 --- a/FRENCH/src/ch04-01-what-is-ownership.md +++ b/FRENCH/src/ch04-01-what-is-ownership.md @@ -1247,12 +1247,12 @@ fn calculate_length(s: String) -> (String, usize) { fn main() { let s1 = String::from("hello"); - let (s2, len) = calculer_taille(s1); + let (s2, len) = calculer_longueur(s1); println!("La taille de '{}' est {}.", s2, len); } -fn calculer_taille(s: String) -> (String, usize) { +fn calculer_longueur(s: String) -> (String, usize) { let length = s.len(); // len() renvoie le nombre de caractères d'un String. (s, length) From a1b3a93a2a01516a0af7974844379754546bcb79 Mon Sep 17 00:00:00 2001 From: Jimskapt Date: Sun, 25 Aug 2019 08:56:41 +0200 Subject: [PATCH 053/117] :ambulance: Self-proofreading ch04-02. --- .../src/ch04-02-references-and-borrowing.md | 372 +++++++++--------- FRENCH/src/img/trpl04-05.svg | 87 ++++ FRENCH/src/translation-terms.md | 8 + 3 files changed, 279 insertions(+), 188 deletions(-) create mode 100644 FRENCH/src/img/trpl04-05.svg diff --git a/FRENCH/src/ch04-02-references-and-borrowing.md b/FRENCH/src/ch04-02-references-and-borrowing.md index 97774963d4..a911157c95 100644 --- a/FRENCH/src/ch04-02-references-and-borrowing.md +++ b/FRENCH/src/ch04-02-references-and-borrowing.md @@ -11,10 +11,10 @@ call to `calculate_length`, because the `String` was moved into `calculate_length`. --> -Le problème avec le code du tuple à la fin de la section précédente c'est que -nous avons besoin de retourner le `String` au code appelant pour qu'il puisse -encore utiliser le `String` après l'appel à `calculate_length`, car -l'appartenance du `String` a été déplacée dans `calculate_length`. +La difficulté avec le code du tuple à la fin de la section précédente est que +nous avons besoin de retourner la `String` au code appelant pour qu'il puisse +continuer à utiliser la `String` après l'appel à `calculer_longueur`, car la +`String` a été déplacée dans `calculer_longueur`. -Ici vous allez définir et utiliser une fonction `calculate_length` qui prend -une *référence* à un objet en paramètre plutôt que de s'approprier la valeur : +Voici comment déclarer et utiliser une fonction `calculer_longueur` qui prend +une *référence* à un objet en paramètre plutôt que de prendre possession de la +valeur : -Nom du fichier : src/main.rs +Fichier : src/main.rs -Premièrement, remarquez que tout le code avec le tuple dans la déclaration des -variables et dans le retour de la fonction a été enlevé. Ensuite, on peut -constater que nous envoyons `&s1` dans `calculate_length`, et que dans sa -définition, nous utilisons `&String` plutôt que `String`. +Premièrement, on peut observer que tout le code des *tuples* dans la déclaration +des variables et dans la valeur de retour de la fonction a été enlevé. +Deuxièmement, remarquez que nous passons `&s1` dans `calculer_longueur`, et que +dans sa déclaration, nous utilisons `&String` plutôt que `String`. Ces esperluettes sont des *références*, et elles permettent de vous référer à -une valeur sans se l'approprier. L'illustration 4-5 nous montre cela dans un -diagramme. +une valeur sans en prendre possession. L'illustration 4-5 nous montre cela dans +un schéma. -&String s pointing at String s1 +&String s qui pointe vers la String s1 -Illustration 4-5 : `&String s` pointe sur `String s1` +Illustration 4-5 : Un schéma de la `&String s` qui pointe +vers la `String s1` -> Note : l'opposé du référencement en utilisant `&` est le *déréférencement*, -> qui est effectué par l'opérateur de déréférencement, `*`. Nous allons voir -> quelques utilisations de l'opérateur de déréférencement dans le Chapitre 8 et -> nous discuterons des détails du déréférencement dans le Chapitre 15. +> Remarque : l'opposé de la création de références avec `&` est le +> *déréférencement*, qui s'effectue avec l'opérateur de déréférencement, `*`. +> Nous allons voir quelques utilisations de l'opérateur de déréférencement dans +> le chapitre 8 et nous aborderons les détails du déréférencement dans le +> chapitre 15. -Regardons de plus près les appels de fonction utilisées : +Regardons de plus près l'appel à la fonction : ```rust -# fn calculate_length(s: &String) -> usize { +# fn calculer_longueur(s: &String) -> usize { # s.len() # } let s1 = String::from("hello"); -let len = calculate_length(&s1); +let long = calculer_longueur(&s1); ``` La syntaxe `&s1` nous permet de créer une référence qui se *réfère* à la valeur -de `s1` mais ne s'approprie pas. Par ce qu'elle ne se l'approprie pas, la -valeur qu'elle désigne ne sera pas libérée quand la référence sortira de la -portée. +de `s1` mais n'en pas possession. Et comme elle n'en pas possession, la valeur +sur laquelle elle pointe désigne ne sera pas libérée quand cette référence +sortira de la portée. De la même manière, la signature de la fonction utilise `&` pour indiquer que -le type de paramètre `s` est une référence. Ajoutons quelques commentaires -explicatifs : +le type du paramètre `s` est une référence. Ajoutons quelques commentaires +explicatifs : ```rust -fn calculate_length(s: &String) -> usize { // s est une référence à un String +fn calculer_longueur(s: &String) -> usize { // s est une référence à une String s.len() -} // Ici, s sort de la porté. Mais comme elle ne s'approprie pas ce dont elle - // fait référence, il ne se passe rien. +} // Ici, s sort de la portée. Mais comme elle ne prend pas possession ce dont + // à quoi elle fait référence, il ne se passe rien. ``` La portée dans laquelle la variable `s` est en vigueur est la même que toute -portée de paramètre de fonction, mais nous ne libérons pas ce sur quoi cette -référence pointe quand elle sort de la portée, car nous ne nous l'avons pas -approprié. Les fonctions qui ont des références en paramètres au lieu des -valeurs effectives veulent dire que nous n'avons pas besoin de retourner les -valeurs pour rendre leur appartenance, puis nous n'avons jamais eu -l'appartenance. +portée d'un paramètre de fonction, mais nous ne libérons pas ce sur quoi cette +référence pointe quand elle sort de la portée, car nous ne nous n'en prenons pas +possession. Lorsque les fonctions ont des références en paramètres au lieu des +valeurs réelles, nous n'avons pas besoin de retourner les valeurs pour les +rendre, car nous n'en avons jamais pris possession. Donc qu'est-ce qui se passe si nous essayons de modifier quelque chose que nous -empruntons ? Essayez le code dans l'entrée 4-4. Spoiler : cela ne fonctionne -pas ! +empruntons ? Essayez le code dans l'encart 4-6. Attention, spoiler : cela ne +fonctionne pas ! -Nom du fichier : src/main.rs +Fichier : src/main.rs -```rust,ignore +```rust,ignore,does_not_compile fn main() { let s = String::from("hello"); - change(&s); + changer(&s); } -fn change(some_string: &String) { - some_string.push_str(", world"); +fn changer(texte: &String) { + texte.push_str(", world"); } ``` @@ -237,14 +239,14 @@ fn change(some_string: &String) { Listing 4-6: Attempting to modify a borrowed value --> -Entrée 4-4: tentative de modification d'une valeur +Entrée 4-6 : Tentative de modification d'une valeur empruntée. -Voici l'erreur : +Voici l'erreur : - ```text -error[E0596]: cannot borrow immutable borrowed content `*some_string` as mutable +error[E0596]: cannot borrow immutable borrowed content `*texte` as mutable --> error.rs:8:5 | -7 | fn change(some_string: &String) { - | ------- use `&mut String` here to make mutable -8 | some_string.push_str(", world"); - | ^^^^^^^^^^^ cannot borrow as mutable +7 | fn changer(texte: &String) { + | ------- use `&mut String` here to make mutable +8 | texte.push_str(", world"); + | ^^^^^ cannot borrow as mutable ``` Comme les variables sont immuables par défaut, les références le sont aussi. -Nous ne sommes pas autorisés à modifier une chose quand nous avons une -référence vers elle. +Nous ne sommes pas autorisés à modifier une chose quand nous avons une référence +vers elle. -### Les références modifiables +### Les références mutables -Nous pouvons résoudre l'erreur dans le code de l'entrée 4-4 avec une petite -modification : +Nous pouvons résoudre l'erreur du code de l'encart 4-6 avec une petite +modification : -Nom de fichier : src/main.rs +Fichier : src/main.rs -Premièrement, nous devons modifier `s` pour être `mut`. Ensuite, nous devons -créer une référence modifiable avec `&mut s` et prendre une référence -modifiable avec `some_string: &mut String`. +D'abord, nous avons dû modifier `s` pour être `mut`. Ensuite, nous avons dû +créer une référence mutable avec `&mut s` et accepter de prendre une référence +mutable avec `texte: &mut String`. -Mais les références modifiables ont une grosse restriction : vous ne pouvez -avoir qu'une seule référence modifiable pour un article de donnée précis dans -une portée précise. Le code suivant va échouer : +Mais les références mutables ont une grosse contrainte : vous ne pouvez avoir +qu'une seule référence mutable pour chaque donnée dans chaque portée. Le code +suivant va échouer : -Nom de fichier : src/main.rs +Fichier : src/main.rs -```rust,ignore +```rust,ignore,does_not_compile let mut s = String::from("hello"); let r1 = &mut s; let r2 = &mut s; + +println!("{}, {}", r1, r2); ``` -Voici l'erreur : +Voici l'erreur : - - -```text -error[E0499]: cannot borrow `s` as mutable more than once at a time - --> borrow_twice.rs:5:19 - | -4 | let r1 = &mut s; - | - first mutable borrow occurs here -5 | let r2 = &mut s; - | ^ second mutable borrow occurs here -6 | } - | - first borrow ends here -``` -Cette restriction autorise les mutations, mais de façon très contrôlée. C'est -ce avec quoi les nouveaux Rustacéens ont du mal, car la plupart des langages -vous permettent de modifier les données quand vous voulez. L'avantage de cette -restriction c'est que Rust peut empêcher la concurrence des données au moment -de la compilation. +Cette contrainte autorise les mutations, mais de manière très contrôlée. C'est +quelque chose que les nouveaux Rustacés ont du mal à surmonter, car la plupart +des langages vous permettent de modifier les données quand vous le voulez. -La *concurrence des données* ressemble à une concurrence critique et se produit -quand ces trois facteurs se combinent : +L'avantage d'avoir cette contrainte est que Rust peut empêcher les accès +concurrent au moment de la compilation. Un *accès concurrent* est une situation +de concurrence qui se produit lorsque ces trois facteurs se combinent : -1. Un ou plusieurs pointeurs accèdent à la même donnée au même moment. -2. Au moins un des pointeurs est utilisé pour écrire dans les données. -3. On n'utilise pas de processus pour synchroniser l'accès aux données. +* Deux pointeurs ou plus accèdent à la même donnée au même moment. +* Au moins un des pointeurs est utilisé pour écrire dans cette donnée. +* On n'utilise aucun système pour synchroniser l'accès aux données. -La concurrence des données provoque des comportements inexpliqués et il peut -alors être difficile de diagnostiquer et résoudre le problème lorsque vous -essayez de les traquer au moment de l'exécution; Rust évite que ce problème -arrive parcequ'il ne va même pas compiler le code avec de la concurrence de -données ! +L'accès concurrent provoque des comportements incontrôlés et rend difficile le +diagnostic et la résolution de problèmes lorsque vous essayez de les reproduire +au moment de l'exécution; Rust évite ce problème parce qu'il ne va pas compiler +le code avec un accès concurrent ! -Comme toujours, nous pouvons utiliser des accolades pour créer une nouvelle -portée, pour nous permettre d'avoir plusieurs références modifiables, mais pas -*simultanées* : +Comme d'habitude, nous pouvons utiliser des accolades pour créer une nouvelle +portée, pour nous permettre d'avoir plusieurs références mutables, mais pas en +*simultané* : -Une règle similaire existe pour mélanger les références immuables et -modifiables. Ce code va mener à une erreur : +Une règle similaire existe pour combiner les références immuables et mutables. +Ce code va mener à une erreur : -```rust,ignore +```rust,ignore,does_not_compile let mut s = String::from("hello"); let r1 = &s; // sans problème let r2 = &s; // sans problème let r3 = &mut s; // GROS PROBLEME + +println!("{}, {}, and {}", r1, r2, r3); ``` -Voici l'erreur : +Voici l'erreur : ```text -error[E0502]: cannot borrow `s` as mutable because it is also borrowed as -immutable - --> borrow_thrice.rs:6:19 +error[E0502]: cannot borrow `s` as mutable because it is also borrowed as immutable + -- > src/main.rs:6:14 | -4 | let r1 = &s; // no problem - | - immutable borrow occurs here -5 | let r2 = &s; // no problem -6 | let r3 = &mut s; // BIG PROBLEM - | ^ mutable borrow occurs here -7 | } - | - immutable borrow ends here +4 | let r1 = &s; // sans problème + | -- immutable borrow occurs here +5 | let r2 = &s; // sans problème +6 | let r3 = &mut s; // GROS PROBLEME + | ^^^^^^ mutable borrow occurs here +7 | +8 | println!("{}, {}, and {}", r1, r2, r3); + | -- immutable borrow later used here ``` -Ouah ! Nous ne pouvons pas *non plus* avoir une référence modifiable si nous en -avons une d'immuable. Les utilisateurs d'une référence immuable ne s'attendent -pas à ce que se valeur change soudainement ! Cependant, l'utilisation de -plusieurs références immuables ne pose pas de problème, car personne de ceux -qui lisent uniquement la donnée n'a la possibilité de modifier la lecture de la -donnée par les autres. +Ouah ! Nous ne pouvons pas *non plus* avoir une référence mutable pendant que +nous en avons une autre immuable. Les utilisateurs d'une référence immuable ne +s'attendent pas à ce que se valeur change soudainement ! Cependant, +l'utilisation de plusieurs références immuables ne pose pas de problème, car +personne de n'a la possibilité de modifier la lecture de la donnée par les +autres. -Même si ces erreurs peuvent parfois être frustrantes, souvenez-vous que le -compilateur de Rust nous fait remarquer un futur bogue avant l'heure (au moment -de la compilation plutôt que lors de l'exécution) et vous montre où est -exactement le problème plutôt que vous ayez à traquer pourquoi *des fois* vos -données ne correspondent pas à ce que vous pensiez qu'elles étaient. +Notez bien que la portée d'une référence commence dès qu'elle est introduite et +se poursuit jusqu'au dernier endroit où cette référence est utilisée. Par +exemple, le code suivant va se compiler car la dernière utilisation de la +référence immuable est située avant l'introduction de la référence mutable : -The scopes of the immutable references `r1` and `r2` end after the `println!` -where they are last used, which is before the mutable reference `r3` is -created. These scopes don’t overlap, so this code is allowed. +Les portées des références immuables `r1` et `r2` se terminent après le +`println!` où elles sont utilisées pour la dernière fois, qui se situe avant que +la référence mutable `r3` soit créée. Ces portées ne se chevauchent pas, donc ce +code est autorisé. -Even though borrowing errors may be frustrating at times, remember that it’s -the Rust compiler pointing out a potential bug early (at compile time rather -than at runtime) and showing you exactly where the problem is. Then you don’t -have to track down why your data isn’t what you thought it was. +Même si ces erreurs d'emprunt peuvent parfois être frustrantes, souvenez-vous +que le compilateur de Rust nous fait signale un potentiel bogue avant l'heure +(au moment de la compilation plutôt que l'exécution) et vous montre où est +exactement le problème. Ainsi, vous n'avez plus à chercher pourquoi vos données +ne correspondent pas à ce que vous pensiez qu'elles devraient être. -### Références en suspension +### Les références sautillantes -Avec les langages qui utilisent les pointeurs, c'est facile de créer par erreur -un *pointeur en suspension*, qui est un pointeur qui désigne un endroit dans la -mémoire qui a été donné par quelqu'un d'autre, en libérant une partie de la -mémoire, mais en conservant un pointeur vers cette mémoire. En revanche, dans -Rust, le compilateur garantie que les références ne seront jamais des -références en suspension : si nous avons une référence vers des données, le -compilateur va s'assurer que cette donnée ne vas pas sortir de la portée avant -que la référence vers cette donnée soit sortie. +Avec les langages qui utilisent les pointeurs, il est facile de créer par erreur +un *pointeur sautillant*, qui est un pointeur qui désigne un endroit dans la +mémoire qui a été donné à quelqu'un d'autre, en libérant de la mémoire tout en +conservant un pointeur vers cette mémoire. En revanche, avec Rust, le +compilateur garantit que les références ne seront jamais des références +sautillantes : si nous avons une référence vers des données, le compilateur va +s'assurer que cette donnée ne va pas sortir de la portée avant que la référence +vers cette donnée en soit elle-même sortie. -Essayons de créer une référence en suspension, que Rust va empêcher avec une -erreur au moment de la compilation : +Essayons de créer une référence sautillante, que Rust va empêcher avec une +erreur au moment de la compilation : -Nom du fichier : src/main.rs +Fichier : src/main.rs -```rust,ignore +```rust,ignore,does_not_compile fn main() { - let reference_to_nothing = dangle(); + let reference_vers_rien = sautillante(); } -fn dangle() -> &String { +fn sautillante() -> &String { let s = String::from("hello"); &s @@ -690,7 +680,7 @@ fn dangle() -> &String { Here’s the error: --> -Voici l'erreur : +Voici l'erreur : dangle.rs:5:16 + --> main.rs:5:16 | -5 | fn dangle() -> &String { - | ^ expected lifetime parameter +5 | fn sautillante() -> &String { + | ^ expected lifetime parameter | = help: this function's return type contains a borrowed value, but there is no value for it to be borrowed from @@ -724,10 +714,10 @@ discuss lifetimes in detail in Chapter 10. But, if you disregard the parts about lifetimes, the message does contain the key to why this code is a problem: --> -Ce message d'erreur parle d'une fonctionnalité que nous n'avons pas encore vu : -les *durées de vie*. Nous allons voir plus en détail les durées de vie dans le -Chapitre 10. Mais, si vous mettez de côté les parties qui parlent de la durée -de vie, le message désigne l'élément de code qui pose problème : +Ce message d'erreur fait référence à une fonctionnalité que nous n'avons pas +encore vu : les *durées de vie*. Nous allons aborder les durées de vie dans le +chapitre 10. Mais, si vous mettez de côté les parties qui parlent de la durée de +vie, le message donne la clé de la raison qui pose problème : -Regardons de plus près ce qui se passe à chaque étape de notre code `dangle` : +Regardons de plus près ce qui se passe exactement à chaque étape de notre code +de `sautillante` : -Filename: src/main.rs +Fichier : src/main.rs -Parce que `s` est créé dans `dangle`, quand le code de `dangle` est terminé, -`s` va être désaloué. Mais nous avions essayé de renvoyer une référence vers -elle. Cela veut dire que cette référence va pointer vers un `String` invalide ! -Ce n'est pas bon. Rust ne nous laissera pas faire cela. +Comme `s` est créé dans `sautillante`, lorsque le code de `sautillante` est +terminé, `s` va être désallouée. Mais nous avons essayé de retourner une +référence vers elle. Cela veut dire que cette référence va pointer vers une +`String` invalide. Ce n'est pas bon ! Rust ne nous laissera pas faire cela. -Ici la solution est de renvoyer le `String` directement : +Ici la solution est de renvoyer la `String` directement : ```rust -fn no_dangle() -> String { +fn pas_sautillante() -> String { let s = String::from("hello"); s @@ -817,8 +815,8 @@ This works without any problems. Ownership is moved out, and nothing is deallocated. --> -Cela fonctionne sans problème. L'appartenance est déplacée, et rien n'est -désaloué. +Cela fonctionne sans problème. La possession est déplacée, et rien n'est +désalloué. -Récapitulons ce que nous avons vu à propos des références : +Récapitulons ce que nous avons vu à propos des références : -1. Vous pouvez avoir *un* des deux cas suivants, mais pas les deux en même -temps : - * Une référence modifiable. - * Un nombre illimité de références immuables. -2. Les références doivent toujours être en vigueur. +* Au même moment, vous pouvez avoir *soit* une référence mutable, *soit* un + nombre quelconque de références immuables. +* Les références doivent toujours être en vigueur. -A l'étape suivante, nous allons aborder un type différent de référence : les -slices. +A l'étape suivante, nous allons aborder un autre type de référence : les +découpages. diff --git a/FRENCH/src/img/trpl04-05.svg b/FRENCH/src/img/trpl04-05.svg new file mode 100644 index 0000000000..b4bf2ebee8 --- /dev/null +++ b/FRENCH/src/img/trpl04-05.svg @@ -0,0 +1,87 @@ + + + + + + +%3 + + + +table0 + +s + +name + +value + +ptr + + + + +table1 + +s1 + +name + +value + +ptr + + +len + +5 + +capacity + +5 + + + +table0:c->table1:borrowee + + + + + +table2 + +index + +value + +0 + +h + +1 + +e + +2 + +l + +3 + +l + +4 + +o + + + +table1:c->table2:pointee + + + + + diff --git a/FRENCH/src/translation-terms.md b/FRENCH/src/translation-terms.md index d3146acecf..7cffea7720 100644 --- a/FRENCH/src/translation-terms.md +++ b/FRENCH/src/translation-terms.md @@ -34,10 +34,14 @@ français. | crash | plantage | - | | crate | crate | nom féminin (une *crate*) | | curly bracket | accolade | - | +| dangling (reference) | (référence) sautillante | - | +| data race | accès concurrent | - | | data representation | modèle de données | - | +| deallocate | désalloué | - | | debug | déboguer | - | | debugging | débogage | - | | dependency | dépendance | - | +| dereferencing | déréférencement | - | | destructure | déstructurer | - | | DevOps | DevOps | - | | dot notation | la notation avec un point | - | @@ -87,6 +91,7 @@ français. | package manager | système de gestion de paquets | - | | panic | panique(r) | - | | parallelism | parallélisme | - | +| parameter | paramètre | - | | PATH | PATH | - | | pattern | motif | - | | pattern-matching | filtrage par motif | - | @@ -94,6 +99,7 @@ français. | prelude | étape préliminaire | - | | procedural macro | macro procédurale | - | | project chapter | chapitre de projet | - | +| race condition | situation de concurrence | - | | raw identifier | identificateur brut | - | | README | README | - | | refactoring | remaniement | - | @@ -113,6 +119,7 @@ français. | sidebar | barre latérale | - | | signature | signature | d'une fonction | | signed | signé | - | +| slice | découpage | - | | smart pointer | pointeur intelligent | - | | snip | code inchangé masqué ici | dans un encart | | space | espace | ce mot est féminin quand on parle du caractère typographique | @@ -123,6 +130,7 @@ français. | standard output | sortie standard | - | | statement | instruction | - | | string | chaîne de caractères | - | +| String | String | le type de chaines de caractères de Rust, qui est féminin | | struct | structure | - | | submodule | sous-module | - | | systems concept | notion système | - | From 3f8f2be0c394b2ea03752629757f08a5ff6154e2 Mon Sep 17 00:00:00 2001 From: Jimskapt Date: Sun, 25 Aug 2019 09:24:21 +0200 Subject: [PATCH 054/117] Proofreading translation #52 (ch05-00). --- FRENCH/src/SUMMARY.md | 2 ++ FRENCH/src/ch05-00-structs.md | 16 ++++++++-------- FRENCH/src/translation-terms.md | 2 ++ 3 files changed, 12 insertions(+), 8 deletions(-) diff --git a/FRENCH/src/SUMMARY.md b/FRENCH/src/SUMMARY.md index 2b62457da4..c5d752d357 100644 --- a/FRENCH/src/SUMMARY.md +++ b/FRENCH/src/SUMMARY.md @@ -13,3 +13,5 @@ - [Hello, Cargo!](ch01-03-hello-cargo.md) - [Programmer un jeu de devinettes](ch02-00-guessing-game-tutorial.md) + +- [Utiliser les structures pour structurer des données associées](ch05-00-structs.md) diff --git a/FRENCH/src/ch05-00-structs.md b/FRENCH/src/ch05-00-structs.md index 8942b6cfbf..aa4fe45ec8 100644 --- a/FRENCH/src/ch05-00-structs.md +++ b/FRENCH/src/ch05-00-structs.md @@ -1,6 +1,6 @@ -# Utiliser les structures pour structurer des données apparentées +# Utiliser les structures pour structurer des données associées Une *struct*, ou *structure*, est un type de données personnalisé qui vous -permet de nommer et de rassembler plusieurs valeurs apparentées qui forment +permet de nommer et de rassembler plusieures valeurs associées qui forment un groupe cohérent. -Si vous êtes familier avec un langage orienté objet, une structure est en -quelque sorte l'ensemble des attributs d'un objet. -Dans ce chapitre, nous comparerons les tuples avec les structures, montrerons -comment utiliser les structures et aborderons la définition des méthodes et des -fonctions associées pour spécifier le comportement associé aux données d'une -structure. +Si vous êtes familier avec un langage orienté objet, une structure ressemble à +l'ensemble des attributs d'un objet. +Dans ce chapitre, nous comparerons les tuples avec les structures, nous +montrerons comment utiliser les structures et nous aborderons la définition des +méthodes et des fonctions associées pour spécifier le comportement associé aux +données d'une structure. Les structures et les énumérations (traitées au chapitre 6) sont les fondements de la création de nouveaux types au sein de votre programme pour tirer pleinement parti des vérifications de types effectuées par Rust à la diff --git a/FRENCH/src/translation-terms.md b/FRENCH/src/translation-terms.md index e21c9aeace..454b494fdb 100644 --- a/FRENCH/src/translation-terms.md +++ b/FRENCH/src/translation-terms.md @@ -13,6 +13,7 @@ français. | array | tableau | - | | artifact | artéfact | - | | associated function | fonction associée | - | +| attributes | attributs | - | | binary crate | crate binaire | s'utilise au féminin | | *n*-bit number | nombre encodé sur *n* bits | - | | boolean | booléen | - | @@ -90,6 +91,7 @@ français. | mutable | mutable | modifiable | | Note | remarque | tout en minuscule (sauf en début de phrase) | | numerical characters | chiffres | - | +| object-oriented language | langage orienté objet | - | | operating system | système d'exploitation | - | | ownership | possession | - | | package manager | système de gestion de paquets | - | From 6217fce6afe0a025df58e1df6ed858ee3d2909e2 Mon Sep 17 00:00:00 2001 From: Thomas Ramirez Date: Sun, 25 Aug 2019 09:40:38 +0200 Subject: [PATCH 055/117] :pencil2: Typo fixing on ch05-00 --- FRENCH/src/ch05-00-structs.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/FRENCH/src/ch05-00-structs.md b/FRENCH/src/ch05-00-structs.md index aa4fe45ec8..8f719a07a9 100644 --- a/FRENCH/src/ch05-00-structs.md +++ b/FRENCH/src/ch05-00-structs.md @@ -15,7 +15,7 @@ time type checking. --> Une *struct*, ou *structure*, est un type de données personnalisé qui vous -permet de nommer et de rassembler plusieures valeurs associées qui forment +permet de nommer et de rassembler plusieurs valeurs associées qui forment un groupe cohérent. Si vous êtes familier avec un langage orienté objet, une structure ressemble à l'ensemble des attributs d'un objet. From 27dd97a785794709aa87c51ab697cded41e8163a Mon Sep 17 00:00:00 2001 From: IceTDrinker <49040125+IceTDrinker@users.noreply.github.com> Date: Sun, 25 Aug 2019 22:20:04 +0200 Subject: [PATCH 056/117] Added missing await reserved keyword From : https://doc.rust-lang.org/reference/keywords.html --- src/appendix-01-keywords.md | 1 + 1 file changed, 1 insertion(+) diff --git a/src/appendix-01-keywords.md b/src/appendix-01-keywords.md index 85e675d8a7..6a129e2903 100644 --- a/src/appendix-01-keywords.md +++ b/src/appendix-01-keywords.md @@ -60,6 +60,7 @@ for potential future use. * `abstract` * `async` +* `await` * `become` * `box` * `do` From 0f10093ac5fbd57feb2352e08ee6d3efd66f887c Mon Sep 17 00:00:00 2001 From: Mark Barbone Date: Fri, 30 Aug 2019 12:57:08 -0400 Subject: [PATCH 057/117] Cargo profiles section: replace link to the Cargo book with link to the specific chapter of the Cargo book --- src/ch14-01-release-profiles.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ch14-01-release-profiles.md b/src/ch14-01-release-profiles.md index c150f6a073..ab2400511e 100644 --- a/src/ch14-01-release-profiles.md +++ b/src/ch14-01-release-profiles.md @@ -66,4 +66,4 @@ Cargo will use the defaults for the `dev` profile plus our customization to optimizations than the default, but not as many as in a release build. For the full list of configuration options and defaults for each profile, see -[Cargo’s documentation](https://doc.rust-lang.org/cargo/). +[Cargo’s documentation](https://doc.rust-lang.org/cargo/reference/manifest.html#the-profile-sections). From 9d601e9ee1c273eab01a9f783f00ca50b9d624e4 Mon Sep 17 00:00:00 2001 From: Thomas Ramirez Date: Sat, 31 Aug 2019 20:46:52 +0200 Subject: [PATCH 058/117] Update CONTRIBUTING.md --- FRENCH/CONTRIBUTING.md | 66 +++++++++++++++++++++++++----------------- 1 file changed, 40 insertions(+), 26 deletions(-) diff --git a/FRENCH/CONTRIBUTING.md b/FRENCH/CONTRIBUTING.md index ef5b0d1787..3c992e5e0f 100644 --- a/FRENCH/CONTRIBUTING.md +++ b/FRENCH/CONTRIBUTING.md @@ -9,53 +9,68 @@ We need to coordinate us with the main English terms translations. In this purpose, please refer to the file `/FRENCH/src/translation-terms.md` when you need to translate a technicial term. -*(PS : see next Process `Add a translation term` on this same page)* +*(PS : see the next process `Add a translation term` on this same page)* ### Translation of Rust code -We should translate only the comments and the string text in the rust code. +In rust code, we should translate : +- comment +- string text +- variable name +- struct name (which is custom, that means it not come from *standard library* + or *external crate*) +- enum name (which is custom, that means it not come from *standard library* + or *external crate*) -All the remaining code (and terminal outputs) should stay in English (variables, -methods/functions, instructions, ...). +All the standard code (and terminal outputs) should stay in English. ### Files -The name of all the files should not be translated, so just keep them in -English. +The name of all the files should not be translated, so just keep them unchanged, +in English. Please limit each line of Markdown file to 80 characters (including spaces). You can write your file as you want, but it would be nice to use a tool like [https://www.dcode.fr/text-splitter](https://www.dcode.fr/text-splitter) on your translated paragraphs before commiting. +### Punctuation + +Please use a [non-breaking space](https://en.wikipedia.org/wiki/Non-breaking_space) +instead of space on punctuation who need this space before (like `:`, `!`, `?`, +...). + ## Processes ### Translate flow -*NB : the following `main translate repository` refers to +*NB : the following term `main translate repository` refers to https://github.com/Jimskapt/rust-book-fr* 01. Open or edit an GitHub issue in the *main translate repository* to report to other that you are working on `ch00-00-introduction`. - if someone has reported to work on the same page you want to translate : - if its works is *active* : you should work on another page. - - else : you can fork its repo in the following step 02 (instead of the - *main translate repository*), please mention it in the existing issue. + - else : you can fork his/her repo in the following step 02 (instead of + the *main translate repository*), and please mention this in the + existing issue. - else : just follow the next instructions. -02. Fork the *main translate repository* in GitHub (in your account) +02. Fork the *main translate repository* in GitHub (on your account) 03. `git clone https://github.com/.git` (copy your fork on your hard-disk). You should be on the `french-release` branch by default. -04. `cd ` (go inside your fork folder) +04. `cd ` (go inside your fork folder your previously downloaded) 05. `git checkout -b ` (create your new working branch) 06. Copy the file you want to translate : `/src/ch00-00-introduction.md` into - `/FRENCH/src/ch00-00-introduction.md` + `/FRENCH/src/ch00-00-introduction.md`. Tip : you can use a tool like + [Castor Whispers](https://github.com/Jimskapt/castor_whispers) in order to + copy and mass-comment each paragraphs of this file. 07. Add the text for the link to this file in the `/FRENCH/src/SUMMARY.md`. 08. Comment each English paragraphs of this file. The goal is to keep an *invisible* version of the English book, in order to easily reflect the changes of the English source (english-book) when they occur later, and to - translate them. + easily translate them. 09. Write each of your translated paragraph under each commented English paragraph. - Please quickly read following `Guidelines` currently on this page. @@ -64,9 +79,9 @@ https://github.com/Jimskapt/rust-book-fr* tool like [https://www.dcode.fr/text-splitter](https://www.dcode.fr/text-splitter). 11. (optionnal) `cd FRENCH && mdbook build && cd ..` (build the book in - `/FRENCH/book`). Open its index.html file, and check its correctness. It - also should help you for next task. -12. (optionnal) proofreading you work thanks to services like + `/FRENCH/book`). Open its index.html file in your browser, and check its + correctness. It also should help you for next task. +12. (optionnal) self-proofreading your work thank to services like [bonpatron.fr](https://bonpatron.com). 13. `git add -A && git commit -m ""` (committing your work) @@ -75,27 +90,26 @@ https://github.com/Jimskapt/rust-book-fr* 15. `git push origin` (pushing your work on your fork) 16. In GitHub, create a new pull request from your fork to the main translation repository, in order to mark your work ready for a proofreading. -17. After proofreading (and eventualy some edits from others), it would be +17. After someone proofreading it (and eventualy some edits), it would be merged on `french-release` branch. -### Update from English book +### Update your fork with another fork -01. `git remote add --track master english-book https://github.com/rust-lang/book.git` +01. `git remote add english-book https://github.com/rust-lang/book.git` (Add source of the *English main repository*) 02. `git fetch english-book` (fetching the latest changes from the *English main repository*) 03. `git merge english-book/master` (merging latest changes from *English main repository* on current branch) + +It is also the same to update your fork with the main translate repository. ### Add a translation term *(PS : see previous Guideline `Translation terms` on this same page)* -01. `git checkout -b ` (create your new working - branch) +01. Check if you are one your working branch, or create it (see `Translate flow` + process) 02. Edit the `/FRENCH/src/translation-terms.md` file with your new technical - term translation. -03. Then do a *Push Request (PR)* in order discuss it with the team. -04. While PR is being accepted and merged, you would better use the English word - in your work instead of your translation, and then edit it when the team is - OK with the translation. + term translation. Write it in singular and if necessary, specify the gender + of the translation in `Remarques` column. From 66d9c48aa00400de4515a3904b66f8f1b44be280 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=ABl=20J=2E=20Pr=C3=A9sent?= <36854931+joeljpresent@users.noreply.github.com> Date: Mon, 2 Sep 2019 13:11:58 +0200 Subject: [PATCH 059/117] Proofread ch03-01 --- .../src/ch03-01-variables-and-mutability.md | 132 +++++++++--------- 1 file changed, 66 insertions(+), 66 deletions(-) diff --git a/FRENCH/src/ch03-01-variables-and-mutability.md b/FRENCH/src/ch03-01-variables-and-mutability.md index dde8439400..c0ad2b4759 100644 --- a/FRENCH/src/ch03-01-variables-and-mutability.md +++ b/FRENCH/src/ch03-01-variables-and-mutability.md @@ -13,11 +13,11 @@ encourages you to favor immutability and why sometimes you might want to opt out. --> -Tel qu'abordé au Chapitre 2, par défaut, les variables sont *immuables*. C'est -un des nombreux coups de pouces de Rust pour écrire votre code de façon à +Tel qu'abordé au chapitre 2, par défaut, les variables sont *immuables*. C'est +un des nombreux coups de pouce de Rust pour écrire votre code de façon à garantir la sécurité et la concurrence sans problème. Cependant, vous avez quand même la possibilité de rendre vos variables mutables *(modifiables)*. Explorons -comment et pourquoi Rust vous encourage à favoriser l'immutabilité, et pourquoi +comment et pourquoi Rust vous encourage à favoriser l'immuabilité, et pourquoi parfois vous pourriez choisir d'y renoncer. Ensuite, dans votre nouveau dossier *variables*, ouvrez *src/main.rs* et -remplacez son code par le code suivant qui ne compile pas pour le moment : +remplacez son code par le code suivant qui ne compile pas pour le moment : -Fichier : src/main.rs +Fichier : src/main.rs Sauvegardez et lancez le programme en utilisant `cargo run`. Vous devriez -avoir un message d'erreur comme celui-ci : +avoir un message d'erreur comme celui-ci : -Ce message d'erreur indique que la cause du problème est qu'il est *impossible -d'assigner à deux reprises la variable immuable x* (`cannot assign twice to +Ce message d'erreur indique que la cause du problème est qu'il est *impossible +d'assigner à deux reprises la variable immuable `x`* (`cannot assign twice to immutable variable x`). Mais la mutabilité peut s'avérer très utile. Les variables sont immuables par -défaut; mais comme vous l'avez fait au chapitre 2, vous pouvez les rendre -mutables en ajoutant `mut` devant le nom de la variable. En plus de permettre +défaut ; mais comme vous l'avez fait au chapitre 2, vous pouvez les rendre +mutables en ajoutant `mut` devant le nom de la variable. En plus de permettre à cette valeur de changer, `mut` va signaler l'intention aux futurs lecteurs de ce code que d'autres parties du code vont modifier la valeur de cette variable. @@ -170,13 +170,13 @@ code que d'autres parties du code vont modifier la valeur de cette variable. For example, let’s change *src/main.rs* to the following: --> -Par exemple, modifions *src/main.rs* par : +Par exemple, modifions *src/main.rs* ainsi : -Fichier : src/main.rs +Fichier : src/main.rs -Lorsque nous exécutons le programme, nous obtenons : +Lorsque nous exécutons le programme, nous obtenons : -En utilisant `mut`, nous avons autorisé le changement valeur de `x`, `5` à `6`. -Dans d'autres cas, vous allez vouloir rendre une variable mutable car cela +En utilisant `mut`, nous avons permis à la valeur de `x` de passer de `5` à `6`. +Dans certains cas, on voudra rendre une variable mutable car cela rendra le code plus pratique à écrire que s'il n'utilisait que des variables immuables. @@ -244,13 +244,13 @@ a more functional programming style may be easier to think through, so lower performance might be a worthwhile penalty for gaining that clarity. --> -Il y a d'autres compromis à accepter, en plus de la prévention des bogues. Par +Il y a d'autres compromis à envisager, en plus de la prévention des bogues. Par exemple, dans le cas où vous utiliseriez des grosses structures de données, muter une instance déjà existante peut être plus rapide que copier et retourner une instance nouvellement allouée. Avec des structures de données plus petites, créer de nouvelles instances avec un style de programmation fonctionnelle peut -rendre le code plus facile à comprendre, mais il a été ainsi décidé que la -clarté du code est plus importante que le coût en performances. +rendre le code plus facile à comprendre, donc il peut valoir le coup de +sacrifier un peu de performance pour que le code gagne en clarté. Rendre impossible de changer la valeur d'une variable peut vous avoir rappelé un -autre concept de programmation que de nombreux autres langages possèdent : les +autre concept de programmation que de nombreux autres langages possèdent : les *constantes*. Comme les variables immuables, les constantes sont des valeurs qui sont liées à un nom et qui ne peuvent être modifiées, mais il y a quelques différences entre les constantes et les variables. @@ -278,7 +278,7 @@ immutable by default—they’re always immutable. --> D'abord, vous ne pouvez pas utiliser `mut` avec les constantes. Les constantes -ne sont pas seulement immuables par défaut, elles le sont toujours. +ne sont pas seulement immuables par défaut − elles sont toujours immuables. -Nous déclarons les constantes en utilisant le mot-clé `const` à la place du +On déclare les constantes en utilisant le mot-clé `const` à la place du mot-clé `let`, et le type de la valeur *doit* être indiqué. Nous allons aborder les types et les annotations de types dans la prochaine section, [“Les types de données”][data-types], donc ne vous souciez pas @@ -300,7 +300,7 @@ Constants can be declared in any scope, including the global scope, which makes them useful for values that many parts of code need to know about. --> -Les constantes peuvent être déclarées dans n'importe quel endroit du code, y +Les constantes peuvent être déclarées à n'importe quel endroit du code, y compris la portée globale, ce qui les rend très utiles pour des valeurs que de nombreuses parties de votre code ont besoin de connaître. @@ -322,10 +322,10 @@ underscores can be inserted in numeric literals to improve readability): --> Voici un exemple d'une déclaration de constante où le nom de la constante est -MAX_POINTS` et où sa valeur est définie à 100 000 (avec Rust, la convention de -nommage des constantes est de les écrire toute en majuscule avec des tirets bas +`MAX_POINTS` et où sa valeur est définie à 100 000. (En Rust, la convention de +nommage des constantes est de les écrire tout en majuscule avec des tirets bas entre les mots, et des tirets bas peuvent être ajoutés entre les nombres pour -améliorer la lisibilité) : +améliorer la lisibilité) : ```rust const MAX_POINTS: u32 = 100_000; @@ -339,9 +339,9 @@ maximum number of points any player of a game is allowed to earn or the speed of light. --> -Les constantes sont valables pendant toute la durée d'exécution du programme à -l'intérieur de la portée dans laquelle elles sont déclarées, ce qui en font de -très bon choix lorsque plusieurs parties d'un programme doivent connaître +Les constantes sont valables pendant toute la durée d'exécution du programme +au sein de la portée dans laquelle elles sont déclarées, ce qui en fait de +très bons choix lorsque plusieurs parties du programme doivent connaître certaines valeurs, comme par exemple le nombre maximum de points qu'un joueur est autorisé à gagner ou encore la vitesse de la lumière. @@ -376,20 +376,20 @@ of the `let` keyword as follows: --> Comme nous l'avons vu dans la section -[“Comparer le nombre saisi avec le nombre secret”][comparing-the-guess-to-the-secret-number] -du jeu de devinettes au chapitre 2, nous pouvons déclarer de nouvelles variables -avec le même nom qu'une variable précédente, et que la nouvelle variable +[“Comparer le nombre saisi au nombre secret”][comparing-the-guess-to-the-secret-number] +du jeu de devinettes au chapitre 2, on peut déclarer une nouvelle variable +avec le même nom qu'une variable précédente, et la nouvelle variable masquera la première. Les Rustacés disent que la première variable est *masquée* par la seconde, ce qui signifie que la valeur de la seconde variable sera ce que nous obtiendrons lorsque nous utiliserons cette variable. Nous pouvons créer un masque d'une variable en utilisant le même nom de variable et en réutilisant le -mot-clé `let` comme ci-dessous : +mot-clé `let` comme ci-dessous : -Fichier : src/main.rs +Fichier : src/main.rs Au début, ce programme lie `x` à la valeur `5`. Puis il crée un masque de `x` -en répétant `let x =`, ce qui récupère la valeur originale et lui ajoute `1` : +en répétant `let x =`, en récupérant la valeur d'origine et lui ajoutant `1` : la valeur de `x` est désormais `6`. La troisième instruction `let` crée un autre masque de `x`, en récupérant la précédente valeur et en la multipliant par `2` pour donner à `x` la valeur finale de `12`. Lorsque nous exécutons ce programme, -nous obtenons ceci : +nous obtenons ceci : -La création d'un masque est différent que de marquer une variable comme `mut`, +Créer un masque est différent que de marquer une variable comme étant `mut`, car à moins d'utiliser une nouvelle fois le mot-clé `let`, nous obtiendrons une -erreur de compilation si nous essayons de réassigner cette variable oar -accident. Nous pouvons effectuer quelques transformations sur une valeur avec -`let`, mais la variable doit être immuable après que ces transformations ont été -appliquées. +erreur de compilation si nous essayons de réassigner cette variable par +accident. Nous pouvons effectuer quelques transformations sur une valeur en +utilisant `let`, mais faire en sorte que la variable soit immuable après que ces +transformations ont été appliquées. -Cette erreur indique que nous ne pouvons pas muter le type d'une variable : +L'erreur indique que nous ne pouvons pas muter le type d'une variable : Maintenant que nous avons découvert comment fonctionnent les variables, étudions -désormais les types de données qu'elles peuvent contenir. +les types de données qu'elles peuvent prendre. [comparing-the-guess-to-the-secret-number]: -ch02-00-guessing-game-tutorial.html#comparer-le-nombre-saisi-avec-le-nombre-secret +ch02-00-guessing-game-tutorial.html#comparer-le-nombre-saisi-au-nombre-secret [data-types]: ch03-02-data-types.html#les-types-de-données From 7afab77ecaebba0069aeb1a677bf7ed8a95cc70f Mon Sep 17 00:00:00 2001 From: Jimskapt Date: Tue, 3 Sep 2019 19:00:14 +0200 Subject: [PATCH 060/117] :bug: Correcting non-breaking spaces on ch03-03. --- FRENCH/src/ch03-03-how-functions-work.md | 50 ++++++++++++------------ 1 file changed, 25 insertions(+), 25 deletions(-) diff --git a/FRENCH/src/ch03-03-how-functions-work.md b/FRENCH/src/ch03-03-how-functions-work.md index efb5cfe8aa..e05a8ea11f 100644 --- a/FRENCH/src/ch03-03-how-functions-work.md +++ b/FRENCH/src/ch03-03-how-functions-work.md @@ -25,13 +25,13 @@ Here’s a program that contains an example function definition: Le code Rust utilise le *snake case* comme convention de style de nom des fonctions et des variables. Avec le *snake case*, toutes les lettres sont en minuscule et on utilise des tirets bas pour séparer les mots. Voici un programme -qui est un exemple de définition de fonction : +qui est un exemple de définition de fonction : -Fichier : src/main.rs +Fichier : src/main.rs La version réécrite de `une_autre_fonction` montre comment utiliser un paramètre -avec Rust : +avec Rust : -Fichier : src/main.rs +Fichier : src/main.rs Dans la signature d'une fonction, vous *devez* déclarer le type de chaque -paramètre. C'est un choix délibéré de conception de Rust : demander l'annotation +paramètre. C'est un choix délibéré de conception de Rust : demander l'annotation de type dans la définition d'une fonction fait en sorte que le compilateur n'a presque plus besoin que vous les utilisiez autre part pour qu'il comprenne ce que vous voulez faire. @@ -242,13 +242,13 @@ declarations with commas, like this: --> Lorsque vous souhaitez qu'une fonction ait plusieurs paramètres, séparez les -paramètres avec des virgules, comme ceci : +paramètres avec des virgules, comme ceci : -Fichier : src/main.rs +Fichier : src/main.rs -Fichier : src/main.rs +Fichier : src/main.rs ```rust fn main() { @@ -383,7 +383,7 @@ fn main() { Listing 3-1: A `main` function declaration containing one statement --> -Encart 3-1 : une fonction `main` qui contient une +Encart 3-1 : une fonction `main` qui contient une déclaration -Fichier : src/main.rs +Fichier : src/main.rs ```rust,ignore,does_not_compile fn main() { @@ -461,17 +461,17 @@ new scopes, `{}`, is an expression, for example: Les expressions sont évaluées et composent la plupart de ce que vous allez écrire en Rust. Prenez une simple opération mathématique, comme `5 + 6`, qui est une expression qui s'évalue à la valeur `11`. Les expressions peuvent faire -partie d'une déclaration : dans l'encart 3-1, le `6` dans la déclaration +partie d'une déclaration : dans l'encart 3-1, le `6` dans la déclaration `let y = 6;` est une expression qui s'évalue à la valeur `6`. Appeler une fonction est aussi une expression. Appeler une macro est une expression. Le bloc que nous utilisons pour créer une nouvelle portée, `{}`, est une -expression, par exemple : +expression, par exemple : -Fichier : src/main.rs +Fichier : src/main.rs -Fichier : src/main.rs +Fichier : src/main.rs -Fichier : src/main.rs +Fichier : src/main.rs -Fichier : src/main.rs +Fichier : src/main.rs -Compiler ce code va produire une erreur, comme ci-dessous : +Compiler ce code va produire une erreur, comme ci-dessous : -Voici un simple commentaire : +Voici un simple commentaire : ```rust // hello, world @@ -35,7 +35,7 @@ line. For comments that extend beyond a single line, you’ll need to include Avec Rust, les commentaires commencent avec deux barres obliques et continue jusqu'à la fin de la ligne. Pour des commentaires qui ont plus d'une seule -ligne, vous aurez besoin d'ajouter `//` sur chaque ligne, comme ceci : +ligne, vous aurez besoin d'ajouter `//` sur chaque ligne, comme ceci : Les commentaires peuvent aussi être aussi ajoutés à la fin de la ligne qui -contient du code : +contient du code : -Fichier : src/main.rs +Fichier : src/main.rs Mais parfois vous pourrez les voir utilisés de cette manière, avec le -commentaire sur une ligne séparée au-dessus du code qu'il annote : +commentaire sur une ligne séparée au-dessus du code qu'il annote : -Fichier : src/main.rs +Fichier : src/main.rs Une expression `if` vous permet de diviser votre code en fonction de conditions. -Vous précisez une condition et vous choisissez ensuite : "si cette condition est +Vous précisez une condition et vous choisissez ensuite : "si cette condition est remplie, alors exécuter ce bloc de code. Si votre condition n'est pas remplie, ne pas exécuter ce bloc de code." @@ -41,13 +41,13 @@ the `if` expression. In the *src/main.rs* file, input the following: --> Créez un nouveau projet appelé *branches* dans votre dossier *projects* pour -découvrir les expressions `if`. Dans le fichier *src/main.rs*, écrivez ceci : +découvrir les expressions `if`. Dans le fichier *src/main.rs*, écrivez ceci : -Fichier : src/main.rs +Fichier : src/main.rs -Essayez d'exécuter ce code, vous verrez ceci : +Essayez d'exécuter ce code, vous verrez ceci : Essayons de changer la valeur de `nombre` pour une valeur qui rend la condition -non vérifiée pour voir ce qui se passe : +non vérifiée pour voir ce qui se passe : -Exécutez à nouveau le programme, et regardez le résultat : +Exécutez à nouveau le programme, et regardez le résultat : -Fichier : src/main.rs +Fichier : src/main.rs -La condition `if` vaut `3` cette fois, et Rust lève une erreur : +La condition `if` vaut `3` cette fois, et Rust lève une erreur : Vous pouvez utiliser plusieurs conditions en combinant `if` et `else` dans une -expression `else if`. Par exemple : +expression `else if`. Par exemple : -Fichier : src/main.rs +Fichier : src/main.rs Ce programme peut choisir entre quatre chemins différents. Après l'avoir -exécuté, vous devriez voir le résultat suivant : +exécuté, vous devriez voir le résultat suivant : -Fichier : src/main.rs +Fichier : src/main.rs -Encart 3-2 : assigner le résultat d'une expression `if` à +Encart 3-2 : assigner le résultat d'une expression `if` à une variable La variable `nombre` va avoir la valeur du résultat de l'expression `if`. -Exécutez ce code pour découvrir ce qui va se passer : +Exécutez ce code pour découvrir ce qui va se passer : -Fichier : src/main.rs +Fichier : src/main.rs -Rust a trois types de boucles : `loop`, `while`, et `for`. Essayons chacune +Rust a trois types de boucles : `loop`, `while`, et `for`. Essayons chacune d'elles. -Fichier : src/main.rs +Fichier : src/main.rs -Fichier : src/main.rs +Fichier : src/main.rs -Fichier : src/main.rs +Fichier : src/main.rs -Encart 3-4 : boucle pour chaque élément d'une collection en +Encart 3-4 : boucle pour chaque élément d'une collection en utilisant une boucle `while` -Fichier : src/main.rs +Fichier : src/main.rs -Encart 3-5 : itérer pour chaque élément d'une collection +Encart 3-5 : itérer pour chaque élément d'une collection en utilisant une boucle `for` Voici ce que le décompte aurait donné en utilisant une boucle `for` et une autre -méthode que nous n'avons pas encore vu, `rev`, qui inverse le sens des données : +méthode que nous n'avons pas encore vu, `rev`, qui inverse le sens des données : -Fichier : src/main.rs +Fichier : src/main.rs -Vous y êtes arrivé ! C'était un chapitre important : vous avez appris les +Vous y êtes arrivé ! C'était un chapitre important : vous avez appris les variables, les types scalaires et composés, les fonctions, les commentaires, les expressions `if`, et les boucles ! Si vous voulez pratiquer un peu les concepts abordés dans ce chapitre, voici quelques programmes que vous pouvez essayer de -créer : +créer : -## Qu'est-ce que la possession ? +## Qu'est-ce que la possession ? Tout d'abord, définissons les règles de la possession. Gardez à l'esprit ces -règles pendant que nous travaillons sur des exemples qui les illustrent : +règles pendant que nous travaillons sur des exemples qui les illustrent : -Encart 4-1 : une variable et la portée dans laquelle elle +Encart 4-1 : une variable et la portée dans laquelle elle est en vigueur. -Autrement dit, il y a ici deux étapes importantes : +Autrement dit, il y a ici deux étapes importantes : -Ce type de chaîne de caractères *peut* être mutable : +Ce type de chaîne de caractères *peut* être mutable : -Donc, quelle est la différence ici ? Pourquoi `String` peut être mutable, mais -pourquoi les chaînes de caractères pures ne peuvent pas l'être ? La différence +Donc, quelle est la différence ici ? Pourquoi `String` peut être mutable, mais +pourquoi les chaînes de caractères pures ne peuvent pas l'être ? La différence se trouve dans la façon dont ces deux types travaillent avec la mémoire. -Nous nous occupons de ce premier point : quand nous appelons `String::from`, son +Nous nous occupons de ce premier point : quand nous appelons `String::from`, son implémentation demande la mémoire dont elle a besoin. C'est pratiquement toujours ainsi dans la majorité des langages de programmation. @@ -518,10 +518,10 @@ variable that owns it goes out of scope. Here’s a version of our scope example from Listing 4-1 using a `String` instead of a string literal: --> -Rust prend un chemin différent : la mémoire est automatiquement libérée dès +Rust prend un chemin différent : la mémoire est automatiquement libérée dès que la variable qui la possède sort de la portée. Voici une version de notre exemple de portée de l'encart 4-1 qui utilise un `String` plutôt qu'une chaîne -de caractères pure : +de caractères pure : Ceci est un cas naturel pour lequel nous devons rendre la mémoire de notre -`String` au système d'exploitation : quand `s` sort de la portée. Quand une +`String` au système d'exploitation : quand `s` sort de la portée. Quand une variable sort de la portée, Rust utilise une fonction spéciale pour nous. Cette fonction s'appelle `drop`, et c'est dans celle-ci que l'auteur du `String` a pu mettre le code pour libérer la mémoire. Rust appelle automatiquement `drop` à @@ -565,7 +565,7 @@ l'accolade fermante `}`. > patterns. --> -> Remarque : dans du C++, cette façon de libérer des ressources à la fin de la +> Remarque : dans du C++, cette façon de libérer des ressources à la fin de la > durée de vie d'un élément est parfois appelé *l'acquisition d'une ressource > est une initialisation (RAII)*. La fonction `drop` de Rust vous sera familière > si vous avez déjà utilisé une configuration en RAII. @@ -587,7 +587,7 @@ Examinons une de ces situations dès à présent. #### Ways Variables and Data Interact: Move --> -#### Les interactions entre les variables et les données : les déplacements +#### Les interactions entre les variables et les données : les déplacements Plusieurs variables peuvent interagir avec les mêmes données de différentes -manières avec Rust. Regardons un exemple avec un entier dans l'encart 4-2 : +manières avec Rust. Regardons un exemple avec un entier dans l'encart 4-2 : ```rust let x = 5; @@ -607,7 +607,7 @@ let y = x; to `y` --> -Encart 4-2 : assigner l'entier de la variable `x` à `y` +Encart 4-2 : assigner l'entier de la variable `x` à `y` -Nous pouvons probablement deviner ce qui va se passer : “Assigner la valeur `5` +Nous pouvons probablement deviner ce qui va se passer : “Assigner la valeur `5` à `x`; ensuite faire une copie de cette valeur de `x` et l'assigner à `y`.” Nous avons maintenant deux variables, `x` et `y`, et chacune vaut `5`. C'est effectivement ce qui se passe, car les entiers sont des valeurs simples avec une @@ -628,7 +628,7 @@ taille connue et fixée, et ces deux valeurs `5` sont stockées sur la pile. Now let’s look at the `String` version: --> -Maintenant, essayons une nouvelle version avec `String` : +Maintenant, essayons une nouvelle version avec `String` : ```rust let s1 = String::from("hello"); @@ -642,7 +642,7 @@ value in `s1` and bind it to `s2`. But this isn’t quite what happens. --> Cela ressemble beaucoup au code précédent, donc nous allons supposer que cela -fonctionne pareil que précédemment : ainsi, la seconde ligne va faire une copie +fonctionne pareil que précédemment : ainsi, la seconde ligne va faire une copie de la valeur de `s1` et l'assigner à `s2`. Mais ce n'est pas tout à fait ce qu'il se passe. @@ -655,7 +655,7 @@ heap that holds the contents. --> Regardons l'illustration 4-1 pour découvrir ce qui arrive à `String` sous le -capot. Un `String` est constitué de trois éléments, présents sur la gauche : un +capot. Un `String` est constitué de trois éléments, présents sur la gauche : un pointeur vers la mémoire qui contient le contenu de la chaîne de caractères, une taille, et une capacité. Ce groupe de données est stocké sur la pile. A droite, nous avons la mémoire sur le tas qui contient les données. @@ -667,7 +667,7 @@ nous avons la mémoire sur le tas qui contient les données. holding the value `"hello"` bound to `s1` --> -Illustration 4-1 : représentation d'un `String` dans la +Illustration 4-1 : représentation d'un `String` dans la mémoire qui contient la valeur `"hello"` assignée à `s1`. -Illustration 4-2 : représentation dans la mémoire de la +Illustration 4-2 : représentation dans la mémoire de la variable `s2` qui est une copie du pointeur, de la taille et de la capacité de `s1` @@ -727,7 +727,7 @@ performances d'exécution si les données sur le tas étaient volumineuses. do if Rust copied the heap data as well --> -Illustration 4-3 : une autre possibilité de ce que +Illustration 4-3 : une autre possibilité de ce que pourrait faire `s2 = s1` si Rust copiait aussi les données du tas Vous allez avoir une erreur comme celle-ci, car Rust vous défend d'utiliser la -référence qui n'est plus en vigueur : +référence qui n'est plus en vigueur : ```text error[E0382]: use of moved value: `s1` @@ -819,7 +819,7 @@ passe réellement dans l'illustration 4-4. invalidated --> -Illustration 4-4 : représentation de la mémoire après que +Illustration 4-4 : représentation de la mémoire après que `s1` ai été neutralisée -Cela résout notre problème ! Avec seulement `s2` en vigueur, quand elle +Cela résout notre problème ! Avec seulement `s2` en vigueur, quand elle sortira de la portée, elle seule va libérer la mémoire, et c'est tout. -De plus, cela signifie qu'il y a eu un choix de conception : Rust ne va jamais +De plus, cela signifie qu'il y a eu un choix de conception : Rust ne va jamais créer des copies “profondes” de vos données. Par conséquent, toute copie *automatique* peut être considérée comme peu coûteuse en termes de performances d'exécution. @@ -845,7 +845,7 @@ d'exécution. #### Ways Variables and Data Interact: Clone --> -#### Les interactions entre les variables et les données : le clonage +#### Les interactions entre les variables et les données : le clonage -Voici un exemple d'utilisation de la méthode `clone` : +Voici un exemple d'utilisation de la méthode `clone` : ```rust let s1 = String::from("hello"); @@ -904,7 +904,7 @@ part of which was shown in Listing 4-2, works and is valid: Il y a une autre faille dont on n'a pas encore parlé. Le code suivant utilise des entiers, comme cela a déjà été montré dans l'encart 4-2, il fonctionne et -est correct : +est correct : ```rust let x = 5; @@ -918,7 +918,7 @@ But this code seems to contradict what we just learned: we don’t have a call t `clone`, but `x` is still valid and wasn’t moved into `y`. --> -Mais ce code semble contredire ce que nous venons d'apprendre : nous n'avons +Mais ce code semble contredire ce que nous venons d'apprendre : nous n'avons pas appelé un `clone`, mais `x` est toujours en vigueur et n'a pas été déplacé dans `y`. @@ -969,11 +969,11 @@ be sure, but as a general rule, any group of simple scalar values can be `Copy`. Here are some of the types that are `Copy`: --> -Donc, quels sont les types qui ont `Copy` ? Vous pouvez regarder dans la +Donc, quels sont les types qui ont `Copy` ? Vous pouvez regarder dans la documentation pour un type donné pour vous en assurer, mais de manière générale, tout groupe de valeur scalaire peut être `Copy`, et tout ce qui ne nécessite pas d'affectation de mémoire ou tout autre forme quelconque de ressource est `Copy`. -Voici quelques types qui sont `Copy` : +Voici quelques types qui sont `Copy` : -Fichier : src/main.rs +Fichier : src/main.rs -Encart 4-3 : les fonctions avec les possessions et les +Encart 4-3 : les fonctions avec les possessions et les portées qui sont commentées Renvoyer les valeurs peut aussi transférer leur possession. L'encart 4-4 est un -exemple avec des annotations similaires à celles de l'encart 4-3 : +exemple avec des annotations similaires à celles de l'encart 4-3 : -Fichier : src/main.rs +Fichier : src/main.rs -Encart 4-4 : transferts de possessions des valeurs de +Encart 4-4 : transferts de possessions des valeurs de retour -La possession d'une variable suit toujours le même schéma à chaque fois : +La possession d'une variable suit toujours le même schéma à chaque fois : assigner une valeur à une autre variable la déplace. Quand une variable qui contient des données sur le tas sort de la portée, la valeur va être nettoyée avec `drop` à moins que la donnée ait été déplacée pour être possédée par une @@ -1208,7 +1208,7 @@ function that we might want to return as well. Il est un peu fastidieux de prendre la possession puis ensuite de retourner la possession avec chaque fonction. Et qu'est ce qu'il se passe si nous voulons -qu'une fonction utilise une valeur, mais n'en prenne pas possession ? C'est +qu'une fonction utilise une valeur, mais n'en prenne pas possession ? C'est assez pénible que tout ce que nous envoyons doit être retourné si nous voulons l'utiliser à nouveau, en plus de toutes les données qui découlent de l'exécution de la fonction que nous voulons aussi récupérer. @@ -1217,13 +1217,13 @@ de la fonction que nous voulons aussi récupérer. It’s possible to return multiple values using a tuple, as shown in Listing 4-5. --> -Il est possible de retourner plusieurs valeurs à l'aide d'un tuple, comme ceci : +Il est possible de retourner plusieurs valeurs à l'aide d'un tuple, comme ceci : -Fichier : src/main.rs +Fichier : src/main.rs -Encart 4-5 : retourner la possession des paramètres +Encart 4-5 : retourner la possession des paramètres -Fichier : src/main.rs +Fichier : src/main.rs -Illustration 4-5 : Un schéma de la `&String s` qui pointe +Illustration 4-5 : Un schéma de la `&String s` qui pointe vers la `String s1` -> Remarque : l'opposé de la création de références avec `&` est le +> Remarque : l'opposé de la création de références avec `&` est le > *déréférencement*, qui s'effectue avec l'opérateur de déréférencement, `*`. > Nous allons voir quelques utilisations de l'opérateur de déréférencement dans > le chapitre 8 et nous aborderons les détails du déréférencement dans le @@ -110,7 +110,7 @@ vers la `String s1` Let’s take a closer look at the function call here: --> -Regardons de plus près l'appel à la fonction : +Regardons de plus près l'appel à la fonction : Donc qu'est-ce qui se passe si nous essayons de modifier quelque chose que nous -empruntons ? Essayez le code dans l'encart 4-6. Attention, spoiler : cela ne -fonctionne pas ! +empruntons ? Essayez le code dans l'encart 4-6. Attention, spoiler : cela ne +fonctionne pas ! -Fichier : src/main.rs +Fichier : src/main.rs -Entrée 4-6 : Tentative de modification d'une valeur +Entrée 4-6 : Tentative de modification d'une valeur empruntée. -Voici l'erreur : +Voici l'erreur : Nous pouvons résoudre l'erreur du code de l'encart 4-6 avec une petite -modification : +modification : -Fichier : src/main.rs +Fichier : src/main.rs -Mais les références mutables ont une grosse contrainte : vous ne pouvez avoir +Mais les références mutables ont une grosse contrainte : vous ne pouvez avoir qu'une seule référence mutable pour chaque donnée dans chaque portée. Le code -suivant va échouer : +suivant va échouer : -Fichier : src/main.rs +Fichier : src/main.rs -Voici l'erreur : +Voici l'erreur : ```text error[E0499]: cannot borrow `s` as mutable more than once at a time @@ -407,7 +407,7 @@ these three behaviors occur: L'avantage d'avoir cette contrainte est que Rust peut empêcher les accès concurrent au moment de la compilation. Un *accès concurrent* est une situation -de concurrence qui se produit lorsque ces trois facteurs se combinent : +de concurrence qui se produit lorsque ces trois facteurs se combinent : Une règle similaire existe pour combiner les références immuables et mutables. -Ce code va mener à une erreur : +Ce code va mener à une erreur : -Voici l'erreur : +Voici l'erreur : -Ouah ! Nous ne pouvons pas *non plus* avoir une référence mutable pendant que +Ouah ! Nous ne pouvons pas *non plus* avoir une référence mutable pendant que nous en avons une autre immuable. Les utilisateurs d'une référence immuable ne -s'attendent pas à ce que se valeur change soudainement ! Cependant, +s'attendent pas à ce que se valeur change soudainement ! Cependant, l'utilisation de plusieurs références immuables ne pose pas de problème, car personne de n'a la possibilité de modifier la lecture de la donnée par les autres. @@ -555,7 +555,7 @@ mutable reference is introduced: Notez bien que la portée d'une référence commence dès qu'elle est introduite et se poursuit jusqu'au dernier endroit où cette référence est utilisée. Par exemple, le code suivant va se compiler car la dernière utilisation de la -référence immuable est située avant l'introduction de la référence mutable : +référence immuable est située avant l'introduction de la référence mutable : Essayons de créer une référence sautillante, que Rust va empêcher avec une -erreur au moment de la compilation : +erreur au moment de la compilation : -Fichier : src/main.rs +Fichier : src/main.rs -Voici l'erreur : +Voici l'erreur : Ce message d'erreur fait référence à une fonctionnalité que nous n'avons pas -encore vu : les *durées de vie*. Nous allons aborder les durées de vie dans le +encore vu : les *durées de vie*. Nous allons aborder les durées de vie dans le chapitre 10. Mais, si vous mettez de côté les parties qui parlent de la durée de -vie, le message donne la clé de la raison qui pose problème : +vie, le message donne la clé de la raison qui pose problème : Regardons de plus près ce qui se passe exactement à chaque étape de notre code -de `sautillante` : +de `sautillante` : -Fichier : src/main.rs +Fichier : src/main.rs -Ici la solution est de renvoyer la `String` directement : +Ici la solution est de renvoyer la `String` directement : -Récapitulons ce que nous avons vu à propos des références : +Récapitulons ce que nous avons vu à propos des références : -A l'étape suivante, nous allons aborder un autre type de référence : les +A l'étape suivante, nous allons aborder un autre type de référence : les découpages. From 8b185856856b04461eea7bd6fd60cbecb4213792 Mon Sep 17 00:00:00 2001 From: Jimskapt Date: Thu, 5 Sep 2019 06:44:04 +0200 Subject: [PATCH 066/117] :ok_hand: Correcting proofreading #52 Due to comments on commit 3f8f2be0c394b2ea03752629757f08a5ff6154e2 --- FRENCH/src/SUMMARY.md | 2 +- FRENCH/src/ch05-00-structs.md | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/FRENCH/src/SUMMARY.md b/FRENCH/src/SUMMARY.md index c5d752d357..f97deb8190 100644 --- a/FRENCH/src/SUMMARY.md +++ b/FRENCH/src/SUMMARY.md @@ -14,4 +14,4 @@ - [Programmer un jeu de devinettes](ch02-00-guessing-game-tutorial.md) -- [Utiliser les structures pour structurer des données associées](ch05-00-structs.md) +- [Utiliser les structures pour structurer des données apparentées](ch05-00-structs.md) diff --git a/FRENCH/src/ch05-00-structs.md b/FRENCH/src/ch05-00-structs.md index 8f719a07a9..95e0cd7de5 100644 --- a/FRENCH/src/ch05-00-structs.md +++ b/FRENCH/src/ch05-00-structs.md @@ -1,6 +1,6 @@ -# Utiliser les structures pour structurer des données associées +# Utiliser les structures pour structurer des données apparentées Chaque valeur en Rust est d'un *type* bien déterminé, qui indique à Rust quel -type de données il manipule afin qu'il puisse savoir comment travailler avec. -Nous allons nous intéresser à deux catégories de types de données : les +genre de données il manipule pour qu'il sache comment traiter ces données. +Nous allons nous intéresser à deux catégories de types de données : les scalaires et les composés. +du chapitre 2, nous devons ajouter une annotation de type, comme ceci : ```rust -let deduction: u32 = "42".parse().expect("Ce n'est pas un nombre !"); +let supposition: u32 = "42".parse().expect("Ce n'est pas un nombre !"); ``` src/main.rs:2:9 | -2 | let deduction = "42".parse().expect("Ce n'est pas un nombre !"); - | ^^^^^^^^^ +2 | let supposition = "42".parse().expect("Ce n'est pas un nombre !"); + | ^^^^^^^^^^^ | | | cannot infer type for `_` - | consider giving `deduction` a type + | consider giving `supposition` a type ``` Un type *scalaire* représente une seule valeur. Rust possède quatre types -principaux de scalaires : les entiers, les nombres à virgule flottante, les -booléens et les caractères. Vous les connaissez surement d'autres langages de +principaux de scalaires : les entiers, les nombres à virgule flottante, les +booléens et les caractères. Vous les connaissez sûrement d'autres langages de programmation. Regardons comment ils fonctionnent avec Rust. -Tableau 3-1 : les types d'entier dans Rust +Tableau 3-1 : les types d'entiers en Rust -Chaque variante peut-être signée ou non-signée et possède une taille explicite. -*Signée* et *non-signée* veut dire respectivement que le nombre est possible ou -non d'être négatif et positif — en d'autres termes, si l'on peut lui attribuer -un signe (signé) ou s'il sera toujours positif et que l'on peut donc le -représenter sans un signe (non-signé). C'est comme écrire des nombres sur un -papier : quand le signe est important, le nombre est écrit avec un signe plus -ou un signe moins ; en revanche, quand le nombre est positif, on peut l'écrire -sans son signe. Les nombres signés sont stockés en utilisant un [complément à -deux](https://fr.wikipedia.org/wiki/Compl%C3%A9ment_%C3%A0_deux). +Chaque variante peut-être signée ou non signée et possède une taille explicite. +*Signé* et *non signé* veut dire respectivement que le nombre peut prendre ou +non des valeurs négatives ou positives — en d'autres termes, si l'on peut lui +attribuer un signe (signé) ou s'il sera toujours positif et que l'on peut donc +le représenter sans signe (non signé). C'est comme écrire des nombres sur du +papier : quand le signe est important, le nombre est écrit avec un signe plus +ou un signe moins ; en revanche, quand le nombre est forcément positif, on peut +l'écrire sans son signe. Les nombres signés sont stockés en utilisant le +[complément à deux](https://fr.wikipedia.org/wiki/Compl%C3%A9ment_%C3%A0_deux). -Chaque variante signée peut stocker des nombres allant de -(2n - 1) -à 2n - 1 - 1 inclus, où `n` est le nombre de bits que cette variante -utilise. Un `i8` peut donc stocker des nombres allant de -(27) à -27 - 1, ce qui vaut -128 jusqu'à 127. Les variantes non signées -peuvent stocker des nombres de 0 à 2n - 1, donc un `u8` peut stocker -des nombres allant de 0 à 28 - 1, c'est-à-dire de 0 à 255. +Chaque variante signée peut stocker des nombres allant de −(2*n* − 1) +à 2*n* − 1 − 1 inclus, où *n* est le nombre de bits que cette +variante utilise. +Un `i8` peut donc stocker des nombres allant de −(27) à +27 − 1, c'est-à-dire de −128 à 127. Les variantes non signées peuvent +stocker des nombres de 0 à 2*n* − 1, donc un `u8` peut stocker +des nombres allant de 0 à 28 − 1, c'est-à-dire de 0 à 255. De plus, les types `isize` et `usize` dépendent du type d'ordinateur sur lequel -votre programme va s'exécuter : 64-bits si vous utilisez une architecture 64-bit -ou 32-bits si vous utilisez une architecture 32-bit. +votre programme va s'exécuter : 64 bits si vous utilisez une architecture +64 bits ou 32 bits si vous utilisez une architecture 32 bits. -Vous pouvez écrire des entiers littéraux dans chacune des formes décrites dans -le Tableau 3-2. Notez que chaque nombre littéral excepté l'octet accepte un +Vous pouvez écrire des littéraux d'entiers dans chacune des formes décrites dans +le tableau 3-2. Notez que chaque littéral numérique excepté l'octet accepte un suffixe de type, comme `57u8`, et `_` comme séparateur visuel, comme par exemple `1_000`. @@ -215,7 +216,7 @@ suffixe de type, comme `57u8`, et `_` comme séparateur visuel, comme par exempl Table 3-2: Integer Literals in Rust --> -Tableau 3-2: Les entiers littéraux en Rust +Tableau 3-2 : Les littéraux d'entiers en Rust -| Nombre littéral | Exemple | +| Littéral numérique | Exemple | |------------------------|---------------| | Décimal | `98_222` | | Hexadécimal | `0xff` | @@ -242,10 +243,10 @@ type is generally the fastest, even on 64-bit systems. The primary situation in which you’d use `isize` or `usize` is when indexing some sort of collection. --> -Comment pouvez-vous déterminer le type d'entier à utiliser ? Si vous n'êtes pas +Comment pouvez-vous déterminer le type d'entier à utiliser ? Si vous n'êtes pas sûr, les choix par défaut de Rust sont généralement de bons choix, et le type -d'entier par défaut est le `i32` : c'est souvent le plus rapide, même sur des -systèmes 64-bit. La principale utilisation d'un `isize` ou d'un `usize` est +d'entier par défaut est le `i32` : c'est souvent le plus rapide, même sur les +systèmes 64 bits. La principale utilisation d'un `isize` ou d'un `usize` est lorsque l'on indexe une quelconque collection. Rust possède également deux types primitifs pour les *nombres à virgule -flottante*, qui sont des nombres avec des décimales. Les types à virgule -flottante avec Rust sont les `f32` et les `f64`, qui ont respectivement une +flottante* (ou *flottants*), qui sont des nombres avec des décimales. Les types +de flottants en Rust sont les `f32` et les `f64`, qui ont respectivement une taille en mémoire de 32 bits et 64 bits. Le type par défaut est le `f64` car sur les processeurs récents ce type est quasiment aussi rapide qu'un `f32` mais est plus précis. @@ -323,7 +324,7 @@ plus précis. Here’s an example that shows floating-point numbers in action: --> -Voici un exemple montrant l'utilisation d'un nombre à virgule flottante : +Voici un exemple montrant l'utilisation de nombres à virgule flottante : -Les nombres à virgule flottante sont représentés selon le standard IEEE-754. Le -type `f32` est un nombre à virgule flottante à simple précision, et le `f64` est -à double précision. +Les nombres à virgule flottante sont représentés selon la norme IEEE-754. Le +type `f32` est un flottant à simple précision, et le `f64` est à double +précision. -Rust offre les opérations mathématiques de base que vous auriez besoin pour tous -les types de nombres : addition, soustraction, multiplication, division et -reliquat. Le code suivant montre comment utiliser chacune d'elle avec une -instruction `let` : +Rust offre les opérations mathématiques de base dont vous auriez besoin pour +tous les types de nombres : addition, soustraction, multiplication, division et +modulo. Le code suivant montre comment utiliser chacune d'elles avec une +instruction `let` : -Fichier : src/main.rs +Fichier : src/main.rs -Chaque expression de ces instructions utilisent un opérateur mathématique et -calcule une valeur unique, qui est ensuite attribué à une variable. L'annexe B +Chaque expression de ces instructions utilise un opérateur mathématique et +calcule une valeur unique, qui est ensuite attribuée à une variable. L'annexe B présente une liste de tous les opérateurs que Rust fournit. Comme dans la plupart des langages de programmation, un type booléen a deux -valeurs possibles en Rust : `true` (vrai) et `false` (faux). Les booléens +valeurs possibles en Rust : `true` (vrai) et `false` (faux). Les booléens prennent un octet en mémoire. Le type booléen est désigné en utilisant `bool`. -Par exemple : +Par exemple : -Fichier : src/main.rs +Fichier : src/main.rs Les valeurs booléennes sont principalement utilisées par les structures -conditionnelles, comme l'expression `if`. Nous allons voir comme `if` fonctionne -avec Rust dans la section [“Les structures de contrôle”][control-flow]. +conditionnelles, comme l'expression `if`. Nous aborderons le fonctionnement +de `if` en Rust dans la section +[“Les structures de contrôle”][control-flow]. Jusqu'à présent, nous avons utilisé uniquement des nombres, mais Rust peut aussi -travailler avec des lettres. Le type `char` *(comme character)* est le type de +travailler avec des lettres. Le type `char` (comme *character*) est le type de caractère le plus rudimentaire, et le code suivant va vous montrer une façon de l'utiliser. (A noter que les `char` sont écrits avec des guillemets simples, contrairement aux chaînes, qui utilisent des guillemets doubles.) @@ -495,7 +497,7 @@ contrairement aux chaînes, qui utilisent des guillemets doubles.) Filename: src/main.rs --> -Fichier : src/main.rs +Fichier : src/main.rs Les *types composés* peuvent regrouper plusieurs valeurs dans un seul type. Rust -a deux types composés de base : les *tuples* et les tableaux *(arrays)*. +a deux types composés de base : les *tuples* et les tableaux *(arrays)*. -Un *tuple* est fonctionnalité permettant de regrouper ensemble plusieurs valeurs -de type différent en un seul type composé. Les *tuples* ont une taille fixée : +Un *tuple* est une manière générale de regrouper plusieurs valeurs +de types différents en un seul type composé. Les tuples ont une taille fixée : à partir du moment où ils ont été déclarés, on ne peut pas y ajouter ou enlever des valeurs. @@ -579,13 +581,13 @@ Nous créons un *tuple* en écrivant une liste séparée par des virgules entre parenthèses. Chaque emplacement dans le tuple a un type, et les types de chacune des valeurs dans le tuple n'ont pas forcément besoin d'être les mêmes. Nous avons ajouté des annotations de type dans cet exemple, mais c'est -optionnel : +optionnel : -Fichier : src/main.rs +Fichier : src/main.rs ```rust fn main() { @@ -599,16 +601,16 @@ single compound element. To get the individual values out of a tuple, we can use pattern matching to destructure a tuple value, like this: --> -La variable `tup` est assigné à tout le *tuple*, car un tuple est considéré -comme étant un seul élément composé. Pour obtenir un élément précis de ce -*tuple*, nous pouvons utiliser un filtrage par motif *(pattern matching)* pour -déstructurer les valeurs d'un tuple, comme ceci : +La variable `tup` est liée à tout le tuple, car un tuple est considéré +comme étant un unique élément composé. Pour obtenir un élément précis de ce +tuple, nous pouvons utiliser un filtrage par motif *(pattern matching)* pour +déstructurer ce tuple, comme ceci : -Fichier : src/main.rs +Fichier : src/main.rs -Le programme commence par créer un *tuple* et il l'assigne à la variable `tup`. -Il utilise ensuite un motif avec `let` pour prendre `tup` et le séparer dans -trois variables, `x`, `y`, et `z`. On appelle cela *destructurer*, car il divise -le *tuple* en trois parties. Puis finalement, le programme affiche la valeur de -`y`, qui est `6.4`. +Le programme commence par créer un tuple et il l'assigne à la variable `tup`. +Il utilise ensuite un motif avec `let` pour prendre `tup` et le scinder en +trois variables distinctes : `x`, `y`, et `z`. +On appelle cela *déstructurer*, car il divise le tuple en trois parties. +Puis finalement, le programme affiche la valeur de `y`, qui est `6.4`. -Fichier : src/main.rs +Fichier : src/main.rs -Ce programme crée un tuple, `x`, et ensuite crée une nouvelle variable pour +Ce programme crée un tuple, `x`, puis crée une nouvelle variable pour chaque élément en utilisant leur indice. Comme dans de nombreux langages de programmation, le premier indice d'un tuple est 0. @@ -711,24 +713,24 @@ different from arrays in some other languages because arrays in Rust have a fixed length, like tuples. --> -Un autre moyen d'avoir une collection de plusieurs valeurs est de le faire avec -un *tableau*. Contrairement au *tuple*, chaque élément du tableau doit être du +Un autre moyen d'avoir une collection de plusieurs valeurs est d'utiliser +un *tableau*. Contrairement aux tuples, chaque élément d'un tableau doit être du même type. Les tableaux de Rust diffèrent de ceux de certains autres langages -car les tableaux de Rust ont une taille fixe, comme les *tuple*. +car les tableaux de Rust ont une taille fixe, comme les tuples. -Avec Rust, les valeurs qui stockées dans un tableau sont écrites dans une -liste séparée par des virgules entre des crochets : +Avec Rust, les valeurs stockées dans un tableau sont écrites dans une +liste séparée par des virgules entre des crochets : -Fichier : src/main.rs +Fichier : src/main.rs ```rust fn main() { @@ -746,12 +748,12 @@ If you’re unsure whether to use an array or a vector, you should probably use vector. Chapter 8 discusses vectors in more detail. --> -Les tableaux sont utiles quand vous voulez que vos données soient stockées sur +Les tableaux sont utiles quand vous voulez que vos données soient allouées sur la pile *(stack)* plutôt que sur le tas *(heap)* (nous expliquerons la pile et le tas au chapitre 4) ou lorsque vous voulez vous assurer que vous avez toujours un nombre fixe d'éléments. Cependant, un tableau n'est pas aussi flexible qu'un -type vecteur *(vector)*. Un vecteur est un type de collection de données -similaire qui est fourni par la bibliothèque standard qui *est* autorisé à +vecteur *(vector)*. Un vecteur est un type de collection de données +similaire qui est fourni par la bibliothèque standard qui, lui, peut grandir ou rétrécir en taille. Si vous ne savez pas si vous devez utiliser un tableau ou un vecteur, vous devriez probablement utiliser un vecteur. Le chapitre 8 expliquera les vecteurs. @@ -764,10 +766,11 @@ an array because you know it will always contain 12 items: --> Un exemple de cas où vous pourriez avoir recours à un tableau plutôt qu'à un -vecteur est un programme qui nécessite de savoir les noms des mois de l'année. -Il est très improbable qu'un tel programme ai besoin d'ajouter ou de supprimer +vecteur est un programme qui nécessite de connaître les noms des mois de +l'année. +Il est très improbable qu'un tel programme ait besoin d'ajouter ou de supprimer des mois, donc vous pouvez utiliser un tableau car vous savez qu'il contiendra -toujours 12 éléments : +toujours 12 éléments : L'écriture d'un type de tableau de cette manière ressemble à une autre syntaxe -pour initialiser un tableau : si vous voulez créer un tableau qui contient la +pour initialiser un tableau : si vous voulez créer un tableau qui contient la même valeur pour chaque élément, vous pouvez préciser la valeur initiale, suivie par un point-virgule, et ensuite la taille du tableau, le tout entre crochets, -comme ci-dessous : +comme ci-dessous : ```rust let a = [3; 5]; @@ -826,8 +829,8 @@ The array named `a` will contain `5` elements that will all be set to the value more concise way. --> -Le tableau `a` va contenir `5` éléments qui seront auront toutes la valeur -initiale `3`. C'est la même chose qu'écrire `let a = [3, 3, 3, 3, 3];` mais +Le tableau `a` va contenir `5` éléments qui auront tous la valeur +initiale `3`. C'est la même chose que d'écrire `let a = [3, 3, 3, 3, 3];` mais de manière plus concise. Un tableau est un simple bloc de mémoire alloué sur la pile. Vous pouvez accéder -aux éléments d'un tableau en utilisant l'indexation, comme ceci : +aux éléments d'un tableau en utilisant l'indexation, comme ceci : -Fichier : src/main.rs +Fichier : src/main.rs Que se passe-t-il quand vous essayez d'accéder à un élément d'un tableau qui se -trouve après la fin du tableau ? Imaginons que vous changiez l'exemple par le +trouve après la fin du tableau ? Imaginons que vous changiez l'exemple par le code suivant, qui va compiler mais qui va quitter avec une erreur quand il sera -exécuté : +exécuté : -Fichier : src/main.rs +Fichier : src/main.rs -Exécuter ce code en utilisant `cargo run` va donner le résultat suivant : +Exécuter ce code en utilisant `cargo run` va donner le résultat suivant : ```text $ cargo run @@ -953,9 +956,9 @@ length, Rust will panic. La compilation n'a pas produit d'erreur, mais le programme a rencontré une erreur *à l'exécution* et ne s'est pas terminé avec succès. Quand vous essayez -d'accéder à un élément en utilisant l'indexation, Rust va vérifier si l'indice +d'accéder à un élément en utilisant l'indexation, Rust va vérifier que l'indice que vous avez demandé est plus petit que la taille du tableau. Si l'indice est -plus grand ou égal à la taille du tableau, Rust va *paniquer*. +supérieur ou égal à la taille du tableau, Rust va *paniquer*. C'est un premier exemple pratique des principes de sécurité de Rust. Dans de -nombreux langages de bas-niveau, ce genre de vérification n'est pas effectuée, +nombreux langages de bas niveau, ce genre de vérification n'est pas effectuée, et quand vous utilisez un indice incorrect, de la mémoire invalide peut être récupérée. Rust vous protège de ce genre d'erreur en quittant immédiatement -l'exécution au lieu de continuer à accéder à ce qu'il y a en mémoire et +l'exécution au lieu de permettre l'accès en mémoire et continuer son déroulement. Le chapitre 9 expliquera la gestion d'erreurs de Rust. @@ -979,9 +982,10 @@ ch02-00-guessing-game-tutorial.html#comparing-the-guess-to-the-secret-number [control-flow]: ch03-05-control-flow.html#control-flow [unrecoverable-errors-with-panic]: ch09-01-unrecoverable-errors-with-panic.html [strings]: ch08-02-strings.html#storing-utf-8-encoded-text-with-strings +[wrapping]: ../std/num/struct.Wrapping.html --> [comparing-the-guess-to-the-secret-number]: -ch02-00-guessing-game-tutorial.html#comparer-le-nombre-saisi-avec-le-nombre-secret +ch02-00-guessing-game-tutorial.html#comparer-le-nombre-saisi-au-nombre-secret [control-flow]: ch03-05-control-flow.html#les-structures-de-contrôle -[wrapping]: ../std/num/struct.Wrapping.html +[wrapping]: https://doc.rust-lang.org/std/num/struct.Wrapping.html From bb76d1d176ec72c29559d1ec00510e52fa258a92 Mon Sep 17 00:00:00 2001 From: Aleru <41040598+Aleru@users.noreply.github.com> Date: Fri, 13 Sep 2019 07:50:42 -0400 Subject: [PATCH 068/117] Update ch07-05-separating-modules-into-different-files.md --- src/ch07-05-separating-modules-into-different-files.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ch07-05-separating-modules-into-different-files.md b/src/ch07-05-separating-modules-into-different-files.md index 4a039fa83e..4285cbb39c 100644 --- a/src/ch07-05-separating-modules-into-different-files.md +++ b/src/ch07-05-separating-modules-into-different-files.md @@ -76,7 +76,7 @@ that module. ## Summary -Rust lets you organize your packages into crates and your crates into modules +Rust lets you divide a package into multiple crates and a crates into modules so you can refer to items defined in one module from another module. You can do this by specifying absolute or relative paths. These paths can be brought into scope with a `use` statement so you can use a shorter path for multiple uses of From f0e949c2102980c5b30e1cc486608e301cd424ed Mon Sep 17 00:00:00 2001 From: Aleru <41040598+Aleru@users.noreply.github.com> Date: Fri, 13 Sep 2019 07:52:22 -0400 Subject: [PATCH 069/117] Update ch07-05-separating-modules-into-different-files.md --- src/ch07-05-separating-modules-into-different-files.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ch07-05-separating-modules-into-different-files.md b/src/ch07-05-separating-modules-into-different-files.md index 4285cbb39c..3d2c6d0836 100644 --- a/src/ch07-05-separating-modules-into-different-files.md +++ b/src/ch07-05-separating-modules-into-different-files.md @@ -76,7 +76,7 @@ that module. ## Summary -Rust lets you divide a package into multiple crates and a crates into modules +Rust lets you divide a package into multiple crates and a crate into modules so you can refer to items defined in one module from another module. You can do this by specifying absolute or relative paths. These paths can be brought into scope with a `use` statement so you can use a shorter path for multiple uses of From c2cffb139818992fbe0c11d22cce511de3c20da6 Mon Sep 17 00:00:00 2001 From: Aleru <41040598+Aleru@users.noreply.github.com> Date: Fri, 13 Sep 2019 08:28:02 -0400 Subject: [PATCH 070/117] Update ch07-05-separating-modules-into-different-files.md --- src/ch07-05-separating-modules-into-different-files.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ch07-05-separating-modules-into-different-files.md b/src/ch07-05-separating-modules-into-different-files.md index 3d2c6d0836..0a455fb929 100644 --- a/src/ch07-05-separating-modules-into-different-files.md +++ b/src/ch07-05-separating-modules-into-different-files.md @@ -76,7 +76,7 @@ that module. ## Summary -Rust lets you divide a package into multiple crates and a crate into modules +Rust lets you partition a package into multiple crates and a crate into modules so you can refer to items defined in one module from another module. You can do this by specifying absolute or relative paths. These paths can be brought into scope with a `use` statement so you can use a shorter path for multiple uses of From 43393128d8aa94c2eeaa923072aa3d7217f1e963 Mon Sep 17 00:00:00 2001 From: Steve Klabnik Date: Sun, 15 Sep 2019 11:29:00 -0500 Subject: [PATCH 071/117] update thanks to carol's feedback --- src/ch15-02-deref.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ch15-02-deref.md b/src/ch15-02-deref.md index 8e54844173..35e2e50faf 100644 --- a/src/ch15-02-deref.md +++ b/src/ch15-02-deref.md @@ -10,7 +10,7 @@ Let’s first look at how the dereference operator works with regular references Then we’ll try to define a custom type that behaves like `Box`, and see why the dereference operator doesn’t work like a reference on our newly defined type. We’ll explore how implementing the `Deref` trait makes it possible for -smart pointers to work in way similar to references. Then we’ll look at +smart pointers to work in ways similar to references. Then we’ll look at Rust’s *deref coercion* feature and how it lets us work with either references or smart pointers. From 43845095867f61564686d930c818c846eb445c0e Mon Sep 17 00:00:00 2001 From: "Carol (Nichols || Goulding)" Date: Sun, 15 Sep 2019 13:18:07 -0400 Subject: [PATCH 072/117] Update version of Rust used to 1.37 This doesn't update any error messages. Fixes #2074. --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index be8ed09bda..d8247288d4 100644 --- a/.travis.yml +++ b/.travis.yml @@ -3,7 +3,7 @@ dist: trusty language: rust cache: cargo rust: - - 1.31.1 + - 1.37.0 branches: only: - master From 636685fd35ca04a98fa73312d92eb2a46987ac96 Mon Sep 17 00:00:00 2001 From: "Carol (Nichols || Goulding)" Date: Sun, 15 Sep 2019 13:22:48 -0400 Subject: [PATCH 073/117] Update version mentioned on the front page --- src/title-page.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/title-page.md b/src/title-page.md index bc7fb9031b..5e375d31b4 100644 --- a/src/title-page.md +++ b/src/title-page.md @@ -2,7 +2,7 @@ *by Steve Klabnik and Carol Nichols, with contributions from the Rust Community* -This version of the text assumes you’re using Rust 1.31.0 or later with +This version of the text assumes you’re using Rust 1.37.0 or later with `edition="2018"` in *Cargo.toml* of all projects to use Rust 2018 Edition idioms. See the [“Installation” section of Chapter 1][install] to install or update Rust, and see the new [Appendix E][editions] Mais la mutabilité peut s'avérer très utile. Les variables sont immuables par diff --git a/FRENCH/src/ch03-05-control-flow.md b/FRENCH/src/ch03-05-control-flow.md index 765278c4e3..70f64430d7 100644 --- a/FRENCH/src/ch03-05-control-flow.md +++ b/FRENCH/src/ch03-05-control-flow.md @@ -134,7 +134,7 @@ error[E0308]: mismatched types -- > src/main.rs:4:8 | 4 | if number { - | ^^^^^^ expected bool, found integral variable + | ^^^^^^ expected bool, found integer | = note: expected type `bool` found type `{integer}` @@ -324,7 +324,7 @@ error[E0308]: if and else have incompatible types 6 | | } else { 7 | | "six" 8 | | }; - | |_____^ expected integral variable, found &str + | |_____^ expected integer, found &str | = note: expected type `{integer}` found type `&str` diff --git a/FRENCH/src/title-page.md b/FRENCH/src/title-page.md index a343fa773c..dad37a1989 100644 --- a/FRENCH/src/title-page.md +++ b/FRENCH/src/title-page.md @@ -12,14 +12,14 @@ Rust* -Cette version du document suppose que vous utilisez Rust 1.31.0 ou ultérieur +Cette version du document suppose que vous utilisez Rust 1.37.0 ou ultérieur avec `edition="2018"` dans *Cargo.toml* de tous les projets afin d'utiliser les expressions idiomatiques de l'édition 2018 de Rust. Voir la [section “Installation” du chapitre 1][install] From 7882e2479f8ceb852a520b2302a9bc6ff2a011fd Mon Sep 17 00:00:00 2001 From: Jens Date: Mon, 23 Sep 2019 09:57:55 +0200 Subject: [PATCH 075/117] Update src/ch15-03-drop.md Co-Authored-By: Steve Klabnik --- src/ch15-03-drop.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ch15-03-drop.md b/src/ch15-03-drop.md index 3524c17de3..9c2c408667 100644 --- a/src/ch15-03-drop.md +++ b/src/ch15-03-drop.md @@ -84,7 +84,7 @@ functionality. Disabling `drop` isn’t usually necessary; the whole point of th `Drop` trait is that it’s taken care of automatically. Occasionally, however, you might want to clean up a value early. One example is when using smart pointers that manage locks: you might want to force the `drop` method that -releases the lock to run some other code in the same scope can acquire the lock. +releases the lock so that other code in the same scope can acquire the lock. Rust doesn’t let you call the `Drop` trait’s `drop` method manually; instead you have to call the `std::mem::drop` function provided by the standard library if you want to force a value to be dropped before the end of its scope. From 7bf6bb154079d6b3bef3a116f032c73479b3f1f5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=ABl=20J=2E=20Pr=C3=A9sent?= <36854931+joeljpresent@users.noreply.github.com> Date: Fri, 27 Sep 2019 22:11:31 +0200 Subject: [PATCH 076/117] Proofread Chapter 03-04 --- FRENCH/src/ch03-04-comments.md | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/FRENCH/src/ch03-04-comments.md b/FRENCH/src/ch03-04-comments.md index 3a258feb50..68274ce132 100644 --- a/FRENCH/src/ch03-04-comments.md +++ b/FRENCH/src/ch03-04-comments.md @@ -11,10 +11,10 @@ extra explanation is warranted. In these cases, programmers leave notes, or reading the source code may find useful. --> -Tous les développeurs s'efforcent de rendre code facile à comprendre, mais -parfois il est nécessaire d'écrire plus d'explications. Dans ce cas, les -développeurs laissent des notes, appelées *commentaires*, dans leur code source -que le compilateur va ignorer mais que les personnes qui peuvent être utiles +Tous les développeurs s'efforcent de rendre leur code facile à comprendre, mais +parfois il est nécessaire d'écrire des explications supplémentaires. +Dans ce cas, les développeurs laissent des notes, appelées *commentaires*, dans +leur code source que le compilateur va ignorer mais qui peuvent être utiles pour les personnes qui lisent le code source. -Avec Rust, les commentaires commencent avec deux barres obliques et continue -jusqu'à la fin de la ligne. Pour des commentaires qui ont plus d'une seule +Avec Rust, les commentaires commencent avec deux barres obliques et continuent +jusqu'à la fin de la ligne. Pour les commentaires qui font plus d'une seule ligne, vous aurez besoin d'ajouter `//` sur chaque ligne, comme ceci : -Les commentaires peuvent aussi être aussi ajoutés à la fin de la ligne qui +Les commentaires peuvent aussi être aussi ajoutés à la fin d'une ligne qui contient du code : -Mais parfois vous pourrez les voir utilisés de cette manière, avec le +Mais parfois, vous pourrez les voir utilisés de cette manière, avec le commentaire sur une ligne séparée au-dessus du code qu'il annote : Rust a aussi un autre type de commentaire, les commentaires de documentation, -que nous allons aborder au chapitre 14. +que nous aborderons au chapitre 14. From 26f87b6aa98a5ebc49f5d2f451c2ea1c3ec4c298 Mon Sep 17 00:00:00 2001 From: "Carol (Nichols || Goulding)" Date: Mon, 30 Sep 2019 20:13:33 -0400 Subject: [PATCH 077/117] Specify the rustc version we're using in a rust-toolchain file This should be kept in sync with the version we test in .travis.yml. --- rust-toolchain | 1 + 1 file changed, 1 insertion(+) create mode 100644 rust-toolchain diff --git a/rust-toolchain b/rust-toolchain new file mode 100644 index 0000000000..bf50e910e6 --- /dev/null +++ b/rust-toolchain @@ -0,0 +1 @@ +1.37.0 From 5b2740e64a21183465f1632958e822f91859b145 Mon Sep 17 00:00:00 2001 From: "Carol (Nichols || Goulding)" Date: Mon, 30 Sep 2019 20:29:07 -0400 Subject: [PATCH 078/117] Remove the check for unstable features We don't use nightly Rust anymore, nor do we try to land docs for features while they're still unstable, so this check is no longer needed. The tests will just fail if we try to use a feature flag in code listings. --- ci/build.sh | 7 ------ ci/stable-check/Cargo.lock | 4 ---- ci/stable-check/Cargo.toml | 6 ------ ci/stable-check/src/main.rs | 43 ------------------------------------- 4 files changed, 60 deletions(-) mode change 100644 => 100755 ci/build.sh delete mode 100644 ci/stable-check/Cargo.lock delete mode 100644 ci/stable-check/Cargo.toml delete mode 100644 ci/stable-check/src/main.rs diff --git a/ci/build.sh b/ci/build.sh old mode 100644 new mode 100755 index 9ad1781381..c4800f850a --- a/ci/build.sh +++ b/ci/build.sh @@ -4,13 +4,6 @@ set -e export PATH=$PATH:/home/travis/.cargo/bin; -# Feature check -cd ci/stable-check - -cargo run -- ../../src - -cd ../.. - echo 'Spellchecking...' bash ci/spellcheck.sh list echo 'Testing...' diff --git a/ci/stable-check/Cargo.lock b/ci/stable-check/Cargo.lock deleted file mode 100644 index 9a3b307c96..0000000000 --- a/ci/stable-check/Cargo.lock +++ /dev/null @@ -1,4 +0,0 @@ -[root] -name = "stable-check" -version = "0.1.0" - diff --git a/ci/stable-check/Cargo.toml b/ci/stable-check/Cargo.toml deleted file mode 100644 index 691722a0b2..0000000000 --- a/ci/stable-check/Cargo.toml +++ /dev/null @@ -1,6 +0,0 @@ -[package] -name = "stable-check" -version = "0.1.0" -authors = ["steveklabnik "] - -[dependencies] diff --git a/ci/stable-check/src/main.rs b/ci/stable-check/src/main.rs deleted file mode 100644 index 167f1f883a..0000000000 --- a/ci/stable-check/src/main.rs +++ /dev/null @@ -1,43 +0,0 @@ -use std::error::Error; -use std::env; -use std::fs; -use std::fs::File; -use std::io::prelude::*; -use std::path::Path; - -fn main() { - let arg = env::args().nth(1).unwrap_or_else(|| { - println!("Please pass a src directory as the first argument"); - std::process::exit(1); - }); - - match check_directory(&Path::new(&arg)) { - Ok(()) => println!("passed!"), - Err(e) => { - println!("Error: {}", e); - std::process::exit(1); - } - } - -} - -fn check_directory(dir: &Path) -> Result<(), Box> { - for entry in fs::read_dir(dir)? { - let entry = entry?; - let path = entry.path(); - - if path.is_dir() { - continue; - } - - let mut file = File::open(&path)?; - let mut contents = String::new(); - file.read_to_string(&mut contents)?; - - if contents.contains("#![feature") { - return Err(From::from(format!("Feature flag found in {:?}", path))); - } - } - - Ok(()) -} From 26565efc3f62d9dacb7c2c6d0f5974360e459493 Mon Sep 17 00:00:00 2001 From: "Carol (Nichols || Goulding)" Date: Sat, 15 Jun 2019 21:36:15 -0400 Subject: [PATCH 079/117] We can start lines with numbers without creating ordered lists --- src/ch13-01-closures.md | 6 ++---- src/ch15-05-interior-mutability.md | 12 +++++------- src/ch16-02-message-passing.md | 8 +++----- 3 files changed, 10 insertions(+), 16 deletions(-) diff --git a/src/ch13-01-closures.md b/src/ch13-01-closures.md index f679c1431e..56f8ed4586 100644 --- a/src/ch13-01-closures.md +++ b/src/ch13-01-closures.md @@ -133,11 +133,9 @@ The first `if` block calls `simulated_expensive_calculation` twice, the `if` inside the outer `else` doesn’t call it at all, and the code inside the second `else` case calls it once. - - The desired behavior of the `generate_workout` function is to first check -whether the user wants a low-intensity workout (indicated by a number less -than 25) or a high-intensity workout (a number of 25 or greater). +whether the user wants a low-intensity workout (indicated by a number less than +25) or a high-intensity workout (a number of 25 or greater). Low-intensity workout plans will recommend a number of push-ups and sit-ups based on the complex algorithm we’re simulating. diff --git a/src/ch15-05-interior-mutability.md b/src/ch15-05-interior-mutability.md index f43d549244..34c002b2fa 100644 --- a/src/ch15-05-interior-mutability.md +++ b/src/ch15-05-interior-mutability.md @@ -1,16 +1,14 @@ ## `RefCell` and the Interior Mutability Pattern - - *Interior mutability* is a design pattern in Rust that allows you to mutate data even when there are immutable references to that data; normally, this action is disallowed by the borrowing rules. To mutate data, the pattern uses `unsafe` code inside a data structure to bend Rust’s usual rules that govern -mutation and borrowing. We haven’t yet covered unsafe code; we will in -Chapter 19. We can use types that use the interior mutability pattern when we -can ensure that the borrowing rules will be followed at runtime, even though -the compiler can’t guarantee that. The `unsafe` code involved is then wrapped -in a safe API, and the outer type is still immutable. +mutation and borrowing. We haven’t yet covered unsafe code; we will in Chapter +19. We can use types that use the interior mutability pattern when we can +ensure that the borrowing rules will be followed at runtime, even though the +compiler can’t guarantee that. The `unsafe` code involved is then wrapped in a +safe API, and the outer type is still immutable. Let’s explore this concept by looking at the `RefCell` type that follows the interior mutability pattern. diff --git a/src/ch16-02-message-passing.md b/src/ch16-02-message-passing.md index 56181eaf79..6b5c23f87e 100644 --- a/src/ch16-02-message-passing.md +++ b/src/ch16-02-message-passing.md @@ -55,16 +55,14 @@ of the streams will end up in one river at the end. We’ll start with a single producer for now, but we’ll add multiple producers when we get this example working. - - The `mpsc::channel` function returns a tuple, the first element of which is the sending end and the second element is the receiving end. The abbreviations `tx` and `rx` are traditionally used in many fields for *transmitter* and *receiver* respectively, so we name our variables as such to indicate each end. We’re using a `let` statement with a pattern that destructures the tuples; we’ll -discuss the use of patterns in `let` statements and destructuring in -Chapter 18. Using a `let` statement this way is a convenient approach to -extract the pieces of the tuple returned by `mpsc::channel`. +discuss the use of patterns in `let` statements and destructuring in Chapter +18. Using a `let` statement this way is a convenient approach to extract the +pieces of the tuple returned by `mpsc::channel`. Let’s move the transmitting end into a spawned thread and have it send one string so the spawned thread is communicating with the main thread, as shown in From 51c9ab3e5b304e1e62a32d4e00ed1a9f40583d6f Mon Sep 17 00:00:00 2001 From: "Carol (Nichols || Goulding)" Date: Mon, 30 Sep 2019 21:09:58 -0400 Subject: [PATCH 080/117] Move all scripts into tools --- convert-quotes.sh => tools/convert-quotes.sh | 0 doc-to-md.sh => tools/doc-to-md.sh | 0 nostarch.sh => tools/nostarch.sh | 0 3 files changed, 0 insertions(+), 0 deletions(-) rename convert-quotes.sh => tools/convert-quotes.sh (100%) rename doc-to-md.sh => tools/doc-to-md.sh (100%) rename nostarch.sh => tools/nostarch.sh (100%) diff --git a/convert-quotes.sh b/tools/convert-quotes.sh similarity index 100% rename from convert-quotes.sh rename to tools/convert-quotes.sh diff --git a/doc-to-md.sh b/tools/doc-to-md.sh similarity index 100% rename from doc-to-md.sh rename to tools/doc-to-md.sh diff --git a/nostarch.sh b/tools/nostarch.sh similarity index 100% rename from nostarch.sh rename to tools/nostarch.sh From 6290b930cd1903daf61c483eab122d4f2a4c58ba Mon Sep 17 00:00:00 2001 From: "Carol (Nichols || Goulding)" Date: Mon, 30 Sep 2019 21:10:26 -0400 Subject: [PATCH 081/117] Commit autogenerated cargo content --- Cargo.lock | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Cargo.lock b/Cargo.lock index 928f6b1244..dbf955717c 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1,3 +1,5 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. [[package]] name = "aho-corasick" version = "0.5.3" From d69b1058c660abfe1d274c58d39c06ebd5c96c47 Mon Sep 17 00:00:00 2001 From: "Carol (Nichols || Goulding)" Date: Mon, 30 Sep 2019 21:10:38 -0400 Subject: [PATCH 082/117] Fancy quotes --- src/ch03-01-variables-and-mutability.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ch03-01-variables-and-mutability.md b/src/ch03-01-variables-and-mutability.md index b14bba5244..d6a73a092e 100644 --- a/src/ch03-01-variables-and-mutability.md +++ b/src/ch03-01-variables-and-mutability.md @@ -65,7 +65,7 @@ But mutability can be very useful. Variables are immutable only by default; as you did in Chapter 2, you can make them mutable by adding `mut` in front of the variable name. In addition to allowing this value to change, `mut` conveys intent to future readers of the code by indicating that other parts of the code -will be changing this variable's value. +will be changing this variable’s value. For example, let’s change *src/main.rs* to the following: From cf633ee5b9ff2267ef18b03714403dc260ba1615 Mon Sep 17 00:00:00 2001 From: Eric Huss Date: Tue, 1 Oct 2019 08:48:26 -0700 Subject: [PATCH 083/117] Fix tidy error. Upstream tidy doesn't like the whitespace in `ci/build.sh` (no tabs, too many newlines). --- ci/build.sh | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/ci/build.sh b/ci/build.sh index 7b3ae84ef5..13f4509a5b 100755 --- a/ci/build.sh +++ b/ci/build.sh @@ -14,7 +14,6 @@ echo 'Linting for local file paths...' cargo run --bin lfp src echo 'Validating references' for file in src/*.md ; do - echo Checking references in $file - cargo run --quiet --bin link2print < $file > /dev/null + echo Checking references in $file + cargo run --quiet --bin link2print < $file > /dev/null done - From b9d854223183c2bd5d9c94261c72c7fcc7eeccf8 Mon Sep 17 00:00:00 2001 From: Jimskapt Date: Fri, 4 Oct 2019 20:48:05 +0200 Subject: [PATCH 084/117] :package: Updating english book sources. Until commit 38ceba56a8bf4efaa977000b85b7a9df191cb827. --- FRENCH/src/ch03-01-variables-and-mutability.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/FRENCH/src/ch03-01-variables-and-mutability.md b/FRENCH/src/ch03-01-variables-and-mutability.md index 41393ba3d9..768501f912 100644 --- a/FRENCH/src/ch03-01-variables-and-mutability.md +++ b/FRENCH/src/ch03-01-variables-and-mutability.md @@ -157,7 +157,7 @@ But mutability can be very useful. Variables are immutable only by default; as you did in Chapter 2, you can make them mutable by adding `mut` in front of the variable name. In addition to allowing this value to change, `mut` conveys intent to future readers of the code by indicating that other parts of the code -will be changing this variable's value. +will be changing this variable’s value. --> Mais la mutabilité peut s'avérer très utile. Les variables sont immuables par From c824c78d9aa24d517c9f99a8678b58903e519a2f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=ABl=20J=2E=20Pr=C3=A9sent?= <36854931+joeljpresent@users.noreply.github.com> Date: Fri, 4 Oct 2019 20:55:21 +0200 Subject: [PATCH 085/117] Proofread ch03-03 (#87) --- FRENCH/src/ch03-03-how-functions-work.md | 171 +++++++++++------------ 1 file changed, 85 insertions(+), 86 deletions(-) diff --git a/FRENCH/src/ch03-03-how-functions-work.md b/FRENCH/src/ch03-03-how-functions-work.md index e05a8ea11f..27ddb48c3d 100644 --- a/FRENCH/src/ch03-03-how-functions-work.md +++ b/FRENCH/src/ch03-03-how-functions-work.md @@ -12,7 +12,7 @@ declare new functions. --> Les fonctions sont omniprésentes dans le code Rust. Vous avez déjà vu l'une des -fonctions les plus importantes du langage : la fonction `main`, qui est le point +fonctions les plus importantes du langage : la fonction `main`, qui est le point d'entrée de beaucoup de programmes. Vous avez aussi vu le mot-clé `fn`, qui vous permet de déclarer des nouvelles fonctions. @@ -65,7 +65,7 @@ after the function name. The curly brackets tell the compiler where the function body begins and ends. --> -La définition d'une fonction avec Rust commence par `fn` et a un jeu de +La définition d'une fonction avec Rust commence par `fn` et a une paire de parenthèses après le nom de la fonction. Les accolades indiquent au compilateur où le corps de la fonction commence et où il se termine. @@ -78,12 +78,12 @@ as well. Rust doesn’t care where you define your functions, only that they’r defined somewhere. --> -Nous pouvons appeler n'importe quelle fonction que nous avons déclaré en -utilisant son nom, suivi d'un jeu de parenthèses. Comme `une_autre_fonction` +Nous pouvons appeler n'importe quelle fonction que nous avons définie en +utilisant son nom, suivi d'une paire de parenthèses. Comme `une_autre_fonction` est définie dans le programme, elle peut être appelée à l'intérieur de la -fonction `main`. Remarquez que nous avons déclaré `une_autre_fonction` *après* -la fonction `main` dans le code source; nous aurions aussi pu la déclarer avant. -Rust ne se soucie pas de l'endroit où vous déclarez vos fonctions, du moment +fonction `main`. Remarquez que nous avons défini `une_autre_fonction` *après* +la fonction `main` dans le code source ; nous aurions aussi pu la définir avant. +Rust ne se soucie pas de l'endroit où vous définissez vos fonctions, du moment qu'elles sont bien définies quelque part. -Créons un nouveau projet de binaire qui s'appelera *functions* afin d'en +Créons un nouveau projet de binaire qui s'appellera *functions* afin d'en apprendre plus sur les fonctions. Ajoutez l'exemple `une_autre_fonction` dans le *src/main.rs* et exécutez-le. Vous devriez avoir ceci : @@ -142,14 +142,14 @@ variables in a function’s definition or the concrete values passed in when you call a function. --> -Les fonctions peuvent aussi être déclarées avec des *paramètres*, qui sont des +Les fonctions peuvent aussi être définies avec des *paramètres*, qui sont des variables spéciales qui font partie de la signature de la fonction. Quand une fonction a des paramètres, vous pouvez lui fournir des valeurs concrètes avec ces paramètres. Techniquement, ces valeurs concrètes sont appelées des -*arguments*, mais dans une conversation courante, les personnes ont tendance à +*arguments*, mais dans une conversation courante, on a tendance à confondre les termes *paramètres* et *arguments* pour désigner soit les variables dans la définition d'une fonction, soit les valeurs concrètes passées -quand on utilise une fonction. +quand on appelle une fonction. -En exécutant ce programme, vous devriez obtenir ceci : +En exécutant ce programme, vous devriez obtenir ceci : -La déclaration de `une_autre_fonction` a un paramètre appellé `x`. Le type de +La déclaration de `une_autre_fonction` a un paramètre nommé `x`. Le type de `x` a été déclaré comme `i32`. Quand `5` est passé à `une_autre_fonction`, la -macro `println!` place `5` où la paire d'accolades `{}` a été placée dans le -texte de formatage. +macro `println!` place `5` là où la paire d'accolades `{}` a été placée dans la +chaîne de formatage. Dans la signature d'une fonction, vous *devez* déclarer le type de chaque -paramètre. C'est un choix délibéré de conception de Rust : demander l'annotation +paramètre. C'est un choix délibéré de conception de Rust : exiger l'annotation de type dans la définition d'une fonction fait en sorte que le compilateur n'a presque plus besoin que vous les utilisiez autre part pour qu'il comprenne ce que vous voulez faire. @@ -269,8 +269,8 @@ fn main() { } fn une_autre_fonction(x: i32, y: i32) { - println!("La valeur de x est : {}", x); - println!("La valeur de y est : {}", y); + println!("La valeur de x est : {}", x); + println!("La valeur de y est : {}", y); } ``` @@ -282,7 +282,7 @@ in this example. --> Cet exemple crée une fonction avec deux paramètres, chacun d'eux sont du type -`i32`. La fonction affiche ensuite les valeurs valeurs de ses deux paramètres. +`i32`. La fonction affiche ensuite les valeurs de ses deux paramètres. Notez que les paramètres des fonctions n'ont pas besoin d'être du même type, nous sommes dans cette situation uniquement pour les besoins de notre exemple. @@ -312,8 +312,8 @@ $ cargo run Compiling functions v0.1.0 (file:///projects/functions) Finished dev [unoptimized + debuginfo] target(s) in 0.31 secs Running `target/debug/functions` -La valeur de x est : 5 -La valeur de y est : 6 +La valeur de x est : 5 +La valeur de y est : 6 ``` -Comme nous avons appellé la fonction avec la valeur `5` pour `x` et `6` pour +Comme nous avons appelé la fonction avec la valeur `5` pour `x` et `6` pour `y`, deux lignes sont affichées avec ces valeurs. -### Corps de fonction avec des déclarations et des expressions +### Corps de fonction avec des instructions et des expressions -Les corps de fonctions sont constitués d'une série de déclarations qui se -terminent éventuellement par une expression. Jusqu'à présent, nous avons vu des +Les corps de fonctions sont constitués d'une série d'instructions qui se +termine éventuellement par une expression. Jusqu'à présent, nous avons vu des fonctions sans expression à la fin, mais vous avez déjà vu une expression faire -partie d'une déclaration. Comme Rust est un langage basé sur des expressions, -il est important de faire la distinction. Les autres langages ne font pas de -telles distinctions, donc penchons-nous sur ce que sont les déclarations et les +partie d'une instruction. Comme Rust est un langage basé sur des expressions, +il est important de faire la distinction. D'autres langages ne font pas de +telles distinctions, donc penchons-nous sur ce que sont les instructions et les expressions et comment leurs différences influent sur le corps des fonctions. -Nous avons déjà utilisé les déclarations et les expressions. Les *déclarations* -sont des instructions qui déclenchent certaines actions et qui ne retournent -aucune valeur. Les *expressions* sont évaluées pour retourner un résultat. +Nous avons déjà utilisé des instructions et des expressions. Les *instructions* +effectuent des actions et ne retournent aucune valeur. +Les *expressions* sont évaluées pour retourner une valeur comme résultat. Voyons quelques exemples. -Créez une variable et assignez-lui une valeur avec le mot-clé `let` qui fait une -déclaration. Dans l'encart 3-1, `let y = 6;` est une déclaration. +Créer une variable en lui assignant une valeur avec le mot-clé `let` constitue +une instruction. Dans l'encart 3-1, `let y = 6;` est une instruction. Encart 3-1 : une fonction `main` qui contient une -déclaration +instruction -La définition d'une fonction est aussi une déclaration; l'intégralité de -l'exemple précédent est une déclaration à elle toute seule. +La définition d'une fonction est aussi une instruction ; l'intégralité de +l'exemple précédent est une instruction à elle toute seule. -Une déclaration ne retourne pas de valeur. Ainsi, vous ne pouvez pas assigner -le résultat d'une déclaration `let` à une autre variable, comme le code suivant -essaye de le faire; car vous allez tomber sur une erreur : +Une instruction ne retourne pas de valeur. Ainsi, vous ne pouvez pas assigner +le résultat d'une instruction `let` à une autre variable, comme le code suivant +essaye de le faire, car vous obtiendrez une erreur : Quand vous exécutez ce programme, l'erreur que vous obtenez devrait ressembler à -ceci : +ceci : ```text $ cargo run @@ -442,11 +442,11 @@ languages, you can write `x = y = 6` and have both `x` and `y` have the value `6`; that is not the case in Rust. --> -La déclaration `let y = 6` ne retourne pas de valeur, donc cela ne peut pas +L'instruction `let y = 6` ne retourne pas de valeur, donc cela ne peut pas devenir une valeur de `x`. Ceci est différent d'autres langages, comme le C ou -le Ruby, où les déclarations retournent la valeur de la déclaration. Dans ces +Ruby, où l'assignation retourne la valeur de l'assignation. Dans ces langages, vous pouvez écrire `x = y = 6` et avoir ainsi `x` et `y` qui ont -chacun la valeur `6`; cela n'est pas possible avec Rust. +chacun la valeur `6` ; cela n'est pas possible avec Rust. -Les expressions sont évaluées et composent la plupart de ce que vous allez -écrire en Rust. Prenez une simple opération mathématique, comme `5 + 6`, qui est -une expression qui s'évalue à la valeur `11`. Les expressions peuvent faire -partie d'une déclaration : dans l'encart 3-1, le `6` dans la déclaration -`let y = 6;` est une expression qui s'évalue à la valeur `6`. Appeler une -fonction est aussi une expression. Appeler une macro est une expression. Le -bloc que nous utilisons pour créer une nouvelle portée, `{}`, est une -expression, par exemple : +Les expressions sont évaluées et seront ce que vous écrirez le plus en Rust +(hormis les instructions). Prenez une simple opération mathématique, comme +`5 + 6`, qui est une expression qui s'évalue à la valeur `11`. Les expressions +peuvent faire partie d'une instruction : dans l'encart 3-1, le `6` dans +l'instruction `let y = 6;` est une expression qui s'évalue à la valeur `6`. +L'appel de fonction est aussi une expression. L'appel de macro est une +expression. Le bloc que nous utilisons pour créer une nouvelle portée, `{}`, +est une expression, par exemple : -L'expression suivante ... +L'expression suivante… ```rust,ignore { @@ -523,14 +523,14 @@ expression, you turn it into a statement, which will then not return a value. Keep this in mind as you explore function return values and expressions next. --> -... est un bloc qui, dans ce cas, s'évalue à 4. Cette valeur est attribuée à `y` -dans le cadre de la déclaration avec `let`. Remarquez la ligne `x + 1` qui ne se -termine pas par un point-virgule à la fin, ce qui est différent de la plupart -des lignes que vous avez vu précédemment. Les expressions n'ont pas de -points-virgules de fin de ligne. Si vous ajoutez un point-virgule à la fin de -l'expression, vous la transformez en déclaration, qui ne va donc pas retourner -de valeur. Gardez ceci à l'esprit quand vous aborderez prochainement les valeurs -de retour des fonctions ainsi que les expressions. +… est un bloc qui, dans ce cas, s'évalue à `4`. Cette valeur est assignée à `y` +dans le cadre de l'instruction `let`. Remarquez la ligne `x + 1` qui ne se +termine pas par un point-virgule, ce qui est différent de la plupart +des lignes que vous avez vues jusque là. Les expressions n'ont pas de +point-virgule de fin de ligne. Si vous ajoutez un point-virgule à la fin de +l'expression, vous la transformez en instruction, qui ne va donc pas retourner +de valeur. Gardez ceci à l'esprit quand nous aborderons prochainement les +valeurs de retour des fonctions ainsi que les expressions. -Les fonctions peuvent retourner des valeurs au code qui les appellent. Nous -n'avons pas besoin de nommer les valeurs de retour, mais nous devons déclarer -leur type après une flèche (`->`). Dans Rust, la valeur de retour de la fonction -est liée à la valeur de l'expression finale dans le corps de la fonction. Vous -pouvez sortir prématurément d'une fonction en utilisant le mot-clé `return` et -en précisant une valeur, mais la plupart des fonctions vont retourner -implicitement la dernière expression. Voici un exemple d'une fonction qui -retourne une valeur : +Les fonctions peuvent retourner des valeurs au code qui les appelle. +Nous ne nommons pas les valeurs de retour, mais nous devons déclarer +leur type après une flèche (`->`). En Rust, la valeur de retour de la fonction +est la même que la valeur de l'expression finale dans le corps de la fonction. +Vous pouvez sortir prématurément d'une fonction en utilisant le mot-clé `return` +et en précisant la valeur de retour, mais la plupart des fonctions vont +retourner implicitement la dernière expression. +Voici un exemple d'une fonction qui retourne une valeur : -Il n'y a pas d'appel de fonction, de macro, même de déclaration `let` dans la +Il n'y a pas d'appel de fonction, de macro, ni même d'instruction `let` dans la fonction `cinq` — uniquement le nombre `5` tout seul. C'est une fonction parfaitement valide avec Rust. Remarquez que le type de retour de la fonction a -été précisé aussi, avec `-> i32`. Essayez d'exécuter ce code; le résultat +été précisé aussi, avec `-> i32`. Essayez d'exécuter ce code ; le résultat devrait ressembler à ceci : -Ensuite, la fonction `cinq` n'a pas de paramètre et déclare le type de valeur -de retour, mais le corps de la fonction est un simple `5` sans point-virgule car -c'est une expression dont nous voulons retourner la valeur. +Deuxièmement, la fonction `cinq` n'a pas de paramètre et déclare le type de +valeur de retour, mais le corps de la fonction est un simple `5` sans +point-virgule car c'est une expression dont nous voulons retourner la valeur. -Regardons un autre exemple : +Regardons un autre exemple : -Exécuter ce code va afficher `La valeur de x est : 6`. Mais si nous ajoutons un +Exécuter ce code va afficher `La valeur de x est : 6`. Mais si nous ajoutons un point-virgule à la fin de la ligne qui contient `x + 1`, ce qui la transforme -d'une expression à une déclaration, nous obtenons une erreur. +d'une expression à une instruction, nous obtenons une erreur. Le message d'erreur principal, “mismatched types” *(types inadéquats)* donne le -coeur du problème de ce code. La définition de la fonction `plus_un` dit qu'elle -va retourner un `i32`, mais les déclarations ne retournent pas de valeur, ceci +cœur du problème de ce code. La définition de la fonction `plus_un` dit qu'elle +va retourner un `i32`, mais les instructions ne retournent pas de valeur, ceci est donc représenté par `()`, un *tuple* vide. Par conséquent, rien n'est retourné, ce qui contredit la définition de la fonction et provoque une erreur. Rust affiche un message qui peut aider à corriger ce problème : il suggère d'enlever le point-virgule, ce qui va résoudre notre problème. - \ No newline at end of file From 6d3e76820418f2d2bb203233c61d90390b5690f1 Mon Sep 17 00:00:00 2001 From: "Carol (Nichols || Goulding)" Date: Sat, 5 Oct 2019 21:21:10 -0400 Subject: [PATCH 086/117] Update the version of rand we use Chapter 7 was using a newer version but claimed to match ch2 and ch14. --- src/ch02-00-guessing-game-tutorial.md | 62 +++++++++++-------- ...g-paths-into-scope-with-the-use-keyword.md | 6 ++ src/ch14-03-cargo-workspaces.md | 15 +++-- 3 files changed, 52 insertions(+), 31 deletions(-) diff --git a/src/ch02-00-guessing-game-tutorial.md b/src/ch02-00-guessing-game-tutorial.md index 5651b68bd3..a992f192c0 100644 --- a/src/ch02-00-guessing-game-tutorial.md +++ b/src/ch02-00-guessing-game-tutorial.md @@ -373,23 +373,28 @@ code that uses `rand`, we need to modify the *Cargo.toml* file to include the the bottom beneath the `[dependencies]` section header that Cargo created for you: + + Filename: Cargo.toml ```toml [dependencies] - -rand = "0.3.14" +rand = "0.5.5" ``` In the *Cargo.toml* file, everything that follows a header is part of a section that continues until another section starts. The `[dependencies]` section is where you tell Cargo which external crates your project depends on and which versions of those crates you require. In this case, we’ll specify the `rand` -crate with the semantic version specifier `0.3.14`. Cargo understands [Semantic +crate with the semantic version specifier `0.5.5`. Cargo understands [Semantic Versioning][semver] (sometimes called *SemVer*), which is a -standard for writing version numbers. The number `0.3.14` is actually shorthand -for `^0.3.14`, which means “any version that has a public API compatible with -version 0.3.14.” +standard for writing version numbers. The number `0.5.5` is actually shorthand +for `^0.5.5`, which means “any version that has a public API compatible with +version 0.5.5.” [semver]: http://semver.org @@ -398,13 +403,19 @@ Listing 2-2. ```text $ cargo build - Updating registry `https://github.com/rust-lang/crates.io-index` - Downloading rand v0.3.14 - Downloading libc v0.2.14 - Compiling libc v0.2.14 - Compiling rand v0.3.14 + Updating crates.io index + Downloaded rand v0.5.5 + Downloaded libc v0.2.62 + Downloaded rand_core v0.2.2 + Downloaded rand_core v0.3.1 + Downloaded rand_core v0.4.2 + Compiling rand_core v0.4.2 + Compiling libc v0.2.62 + Compiling rand_core v0.3.1 + Compiling rand_core v0.2.2 + Compiling rand v0.5.5 Compiling guessing_game v0.1.0 (file:///projects/guessing_game) - Finished dev [unoptimized + debuginfo] target(s) in 2.53 secs + Finished dev [unoptimized + debuginfo] target(s) in 2.53 s ``` Listing 2-2: The output from running `cargo build` after @@ -422,8 +433,8 @@ their open source Rust projects for others to use. After updating the registry, Cargo checks the `[dependencies]` section and downloads any crates you don’t have yet. In this case, although we only listed -`rand` as a dependency, Cargo also grabbed a copy of `libc`, because `rand` -depends on `libc` to work. After downloading the crates, Rust compiles them and +`rand` as a dependency, Cargo also grabbed `libc` and `rand_core`, because `rand` +depends on those to work. After downloading the crates, Rust compiles them and then compiles the project with the dependencies available. If you immediately run `cargo build` again without making any changes, you @@ -439,7 +450,7 @@ and build again, you’ll only see two lines of output: ```text $ cargo build Compiling guessing_game v0.1.0 (file:///projects/guessing_game) - Finished dev [unoptimized + debuginfo] target(s) in 2.53 secs + Finished dev [unoptimized + debuginfo] target(s) in 2.53s ``` These lines show Cargo only updates the build with your tiny change to the @@ -452,7 +463,7 @@ your part of the code. Cargo has a mechanism that ensures you can rebuild the same artifact every time you or anyone else builds your code: Cargo will use only the versions of the dependencies you specified until you indicate otherwise. For example, what -happens if next week version 0.3.15 of the `rand` crate comes out and +happens if next week version 0.5.6 of the `rand` crate comes out and contains an important bug fix but also contains a regression that will break your code? @@ -464,7 +475,7 @@ the *Cargo.lock* file. When you build your project in the future, Cargo will see that the *Cargo.lock* file exists and use the versions specified there rather than doing all the work of figuring out versions again. This lets you have a reproducible build automatically. In other words, your project will -remain at `0.3.14` until you explicitly upgrade, thanks to the *Cargo.lock* +remain at `0.5.5` until you explicitly upgrade, thanks to the *Cargo.lock* file. #### Updating a Crate to Get a New Version @@ -474,26 +485,25 @@ which will ignore the *Cargo.lock* file and figure out all the latest versions that fit your specifications in *Cargo.toml*. If that works, Cargo will write those versions to the *Cargo.lock* file. -But by default, Cargo will only look for versions greater than `0.3.0` and less -than `0.4.0`. If the `rand` crate has released two new versions, `0.3.15` and -`0.4.0`, you would see the following if you ran `cargo update`: +But by default, Cargo will only look for versions greater than `0.5.5` and less +than `0.6.0`. If the `rand` crate has released two new versions, `0.5.6` and +`0.6.0`, you would see the following if you ran `cargo update`: ```text $ cargo update - Updating registry `https://github.com/rust-lang/crates.io-index` - Updating rand v0.3.14 -> v0.3.15 + Updating crates.io index + Updating rand v0.5.5 -> v0.5.6 ``` At this point, you would also notice a change in your *Cargo.lock* file noting -that the version of the `rand` crate you are now using is `0.3.15`. +that the version of the `rand` crate you are now using is `0.5.6`. -If you wanted to use `rand` version `0.4.0` or any version in the `0.4.x` +If you wanted to use `rand` version `0.6.0` or any version in the `0.6.x` series, you’d have to update the *Cargo.toml* file to look like this instead: ```toml [dependencies] - -rand = "0.4.0" +rand = "0.6.0" ``` The next time you run `cargo build`, Cargo will update the registry of crates diff --git a/src/ch07-04-bringing-paths-into-scope-with-the-use-keyword.md b/src/ch07-04-bringing-paths-into-scope-with-the-use-keyword.md index ea6e51716b..05af46cbdc 100644 --- a/src/ch07-04-bringing-paths-into-scope-with-the-use-keyword.md +++ b/src/ch07-04-bringing-paths-into-scope-with-the-use-keyword.md @@ -241,6 +241,12 @@ In Chapter 2, we programmed a guessing game project that used an external package called `rand` to get random numbers. To use `rand` in our project, we added this line to *Cargo.toml*: + + Filename: Cargo.toml ```toml diff --git a/src/ch14-03-cargo-workspaces.md b/src/ch14-03-cargo-workspaces.md index 8b8c078baf..a662ac219e 100644 --- a/src/ch14-03-cargo-workspaces.md +++ b/src/ch14-03-cargo-workspaces.md @@ -192,12 +192,17 @@ each other. Let’s add the `rand` crate to the `[dependencies]` section in the *add-one/Cargo.toml* file to be able to use the `rand` crate in the `add-one` crate: + + Filename: add-one/Cargo.toml ```toml [dependencies] - -rand = "0.3.14" +rand = "0.5.5" ``` We can now add `use rand;` to the *add-one/src/lib.rs* file, and building the @@ -206,10 +211,10 @@ and compile the `rand` crate: ```text $ cargo build - Updating registry `https://github.com/rust-lang/crates.io-index` - Downloading rand v0.3.14 + Updating crates.io index + Downloaded rand v0.5.5 --snip-- - Compiling rand v0.3.14 + Compiling rand v0.5.5 Compiling add-one v0.1.0 (file:///projects/add/add-one) Compiling adder v0.1.0 (file:///projects/add/adder) Finished dev [unoptimized + debuginfo] target(s) in 10.18 secs From 70a82519e48b8a61f98cabb8ff443d1b21962fea Mon Sep 17 00:00:00 2001 From: Kai Zhang Date: Mon, 14 Oct 2019 02:46:03 +0000 Subject: [PATCH 087/117] fix heading level --- src/appendix-04-useful-development-tools.md | 10 +++++----- src/appendix-05-editions.md | 2 +- src/appendix-07-nightly-rust.md | 2 +- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/src/appendix-04-useful-development-tools.md b/src/appendix-04-useful-development-tools.md index ec40d1cbef..33929bc8d0 100644 --- a/src/appendix-04-useful-development-tools.md +++ b/src/appendix-04-useful-development-tools.md @@ -1,10 +1,10 @@ -# Appendix D - Useful Development Tools +## Appendix D - Useful Development Tools In this appendix, we talk about some useful development tools that the Rust project provides. We’ll look at automatic formatting, quick ways to apply warning fixes, a linter, and integrating with IDEs. -## Automatic Formatting with `rustfmt` +### Automatic Formatting with `rustfmt` The `rustfmt` tool reformats your code according to the community code style. Many collaborative projects use `rustfmt` to prevent arguments about which @@ -29,7 +29,7 @@ on `rustfmt`, see [its documentation][rustfmt]. [rustfmt]: https://github.com/rust-lang/rustfmt -## Fix Your Code with `rustfix` +### Fix Your Code with `rustfix` The rustfix tool is included with Rust installations and can automatically fix some compiler warnings. If you’ve written code in Rust, you’ve probably seen @@ -96,7 +96,7 @@ The `for` loop variable is now named `_i`, and the warning no longer appears. You can also use the `cargo fix` command to transition your code between different Rust editions. Editions are covered in Appendix E. -## More Lints with Clippy +### More Lints with Clippy The Clippy tool is a collection of lints to analyze your code so you can catch common mistakes and improve your Rust code. @@ -158,7 +158,7 @@ For more information on Clippy, see [its documentation][clippy]. [clippy]: https://github.com/rust-lang/rust-clippy -## IDE Integration Using the Rust Language Server +### IDE Integration Using the Rust Language Server To help IDE integration, the Rust project distributes the *Rust Language Server* (`rls`). This tool speaks the [Language Server diff --git a/src/appendix-05-editions.md b/src/appendix-05-editions.md index ac75c4181d..db98ecc5ee 100644 --- a/src/appendix-05-editions.md +++ b/src/appendix-05-editions.md @@ -1,4 +1,4 @@ -# Appendix E - Editions +## Appendix E - Editions In Chapter 1, you saw that `cargo new` adds a bit of metadata to your *Cargo.toml* file about an edition. This appendix talks about what that means! diff --git a/src/appendix-07-nightly-rust.md b/src/appendix-07-nightly-rust.md index d8fd0da776..bace82f2e0 100644 --- a/src/appendix-07-nightly-rust.md +++ b/src/appendix-07-nightly-rust.md @@ -1,4 +1,4 @@ -# Appendix G - How Rust is Made and “Nightly Rust” +## Appendix G - How Rust is Made and “Nightly Rust” This appendix is about how Rust is made and how that affects you as a Rust developer. From 83e1d4f539746401ba1833c849b6c7c730b0b94f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=ABl=20J=2E=20Pr=C3=A9sent?= <36854931+joeljpresent@users.noreply.github.com> Date: Mon, 14 Oct 2019 14:05:42 +0200 Subject: [PATCH 088/117] Proofread Chapter 03-05 --- FRENCH/src/ch03-05-control-flow.md | 189 +++++++++++++++-------------- 1 file changed, 95 insertions(+), 94 deletions(-) diff --git a/FRENCH/src/ch03-05-control-flow.md b/FRENCH/src/ch03-05-control-flow.md index 3be3cf01b7..a32a96decb 100644 --- a/FRENCH/src/ch03-05-control-flow.md +++ b/FRENCH/src/ch03-05-control-flow.md @@ -12,10 +12,10 @@ let you control the flow of execution of Rust code are `if` expressions and loops. --> -Choisir d'exécuter ou non du code en fonction du résultat d'une condition et -choisir d'exécuter du code de façon répétée en fonction du résultat d'une autre -condition sont des instructions élémentaires dans de la plupart des langages de -programmation. Les structures de contrôle les plus courantes sont les +Choisir d'exécuter ou non du code selon qu'une condition est vérifiée et +choisir d'exécuter du code de façon répétée tant qu'une condition est vérifiée +sont des constructions élémentaires dans la plupart des langages de +programmation. Les structures de contrôle les plus courantes en Rust sont les expressions `if` et les boucles. Une expression `if` vous permet de diviser votre code en fonction de conditions. -Vous précisez une condition et vous choisissez ensuite : "si cette condition est -remplie, alors exécuter ce bloc de code. Si votre condition n'est pas remplie, -ne pas exécuter ce bloc de code." +Vous précisez une condition et vous choisissez ensuite : “Si cette condition est +remplie, alors exécuter ce bloc de code. Si la condition n'est pas remplie, +ne pas exécuter ce bloc de code.” -Une expression `if` commence par le mot-clé `if`, et est suivi d'une condition. +Une expression `if` commence par le mot-clé `if`, suivi d'une condition. Dans notre cas, la condition vérifie si oui ou non la variable `nombre` a une valeur inférieure à 5. Le bloc de code que nous voulons exécuter si la condition est vérifiée est placé immédiatement après la condition entre des accolades. Les blocs de code associés à une condition dans une expression `if` sont parfois appelés des *branches*, exactement comme les branches dans les expressions -`match` que nous avons vu dans la section [“Comparer le nombre saisi avec le +`match` que nous avons vu dans la section [“Comparer le nombre saisi au nombre secret”][comparing-the-guess-to-the-secret-number] du chapitre 2. @@ -105,9 +105,9 @@ the condition is false, the program will just skip the `if` block and move on to the next bit of code. --> -Eventuellement, vous pouvez aussi ajouter une expression `else`, ce que nous +Éventuellement, vous pouvez aussi ajouter une expression `else`, ce que nous avons fait ici, pour préciser un bloc alternatif de code qui sera exécuté dans -le cas où le résultat de la condition est faux (elle n'est pas vérifiée). Si +le cas où la condition est fausse (elle n'est pas vérifiée). Si vous ne renseignez pas d'expression `else` et que la condition n'est pas vérifiée, le programme va simplement sauter le bloc de `if` et passer au prochain morceau de code. @@ -116,7 +116,7 @@ prochain morceau de code. Try running this code; you should see the following output: --> -Essayez d'exécuter ce code, vous verrez ceci : +Essayez d'exécuter ce code ; vous verrez ceci : Cette erreur explique que Rust attendait un `bool` mais a obtenu un entier -*(integer)*. Contrairement à des langages comme le Ruby et le Javascript, Rust +*(integer)*. Contrairement à des langages comme Ruby et JavaScript, Rust ne va pas essayer de convertir automatiquement les types non booléens en -booléen. Vous devez être précis et toujours fournir un booléen à la condition +booléens. Vous devez être précis et toujours fournir un booléen à la condition d'un `if`. Si nous voulons que le bloc de code du `if` soit exécuté quand le nombre est différent de `0`, par exemple, nous pouvons changer l'expression `if` par la suivante : @@ -347,7 +347,7 @@ fn main() { } else if nombre % 2 == 0 { println!("Le nombre est divisible par 2"); } else { - println!("Le nombre n'est pas divisible par 4, 3, ou 2"); + println!("Le nombre n'est pas divisible par 4, 3 ou 2"); } } ``` @@ -390,9 +390,10 @@ once it finds one, it doesn’t even check the rest. Quand ce programme s'exécute, il vérifie chaque expression `if` à tour de rôle et exécute le premier bloc dont la condition est vérifiée. Notez que même si 6 est divisible par 2, nous ne voyons pas le message `Le nombre est divisible par -2` du bloc `else`. C'est parce que Rust n'exécute que le bloc de la première -condition vérifiée, et dès lorsqu'il en a trouvé une, il ne va pas chercher à -vérifier les suivantes. +2`, ni le message `Le nombre n'est pas divisible par 4, 3 ou 2` du bloc `else`. +C'est parce que Rust n'exécute que le bloc de la première condition vérifiée, +et dès lors qu'il en a trouvé une, il ne va pas chercher à vérifier les +suivantes. -#### Utiliser `if` dans une déclaration `let` +#### Utiliser `if` dans une instruction `let` Comme `if` est une expression, nous pouvons l'utiliser à droite d'une -déclaration `let`, comme dans l'encart 3-2. +instruction `let`, comme dans l'encart 3-2. -L'expression dans le bloc `if` donne un entier, et l'expession dans le bloc +L'expression dans le bloc `if` donne un entier, et l'expression dans le bloc `else` donne une chaîne de caractères. Ceci ne fonctionne pas car les variables doivent avoir un seul type. Rust a besoin de savoir de quel type est la variable -`nombre` au moment de la compilation, sans exception, afin de vérifier au moment +`nombre` au moment de la compilation, assurément, afin de vérifier au moment de la compilation que son type est valable n'importe où nous utilisons `nombre`. Rust ne serait pas capable de faire cela si le type de `nombre` était déterminé -uniquement à l'exécution; car le compilateur deviendrait plus complexe et nous +uniquement à l'exécution ; car le compilateur deviendrait plus complexe et nous donnerait moins de garanties sur le code s'il devait prendre en compte tous les types hypothétiques pour une variable. @@ -621,7 +622,7 @@ experiment with loops, let’s make a new project called *loops*. Il est parfois utile d'exécuter un bloc de code plus d'une seule fois. Dans ce but, Rust propose plusieurs types de *boucles*. Une boucle parcourt le code à -l'intérieur du corps de la boucle jusqu'à la fin, et retourne immédiatement au +l'intérieur du corps de la boucle jusqu'à la fin et recommence immédiatement du début. Pour tester les boucles, créons un nouveau projet appelé *loops*. Par exemple, changez le fichier *src/main.rs* dans votre dossier *loops* comme -ceci : +ceci : -Quand nous exécutons ce programme, nous voyons `A nouveau !` écrit encore et -encore, continuellement jusqu'à ce qu'on arrête le programme manuellement. La +Quand nous exécutons ce programme, nous voyons `À nouveau !` s'afficher encore +et encore en continu jusqu'à ce qu'on arrête le programme manuellement. La plupart des terminaux utilisent un raccourci clavier, ctrl-c, pour arrêter un programme qui est bloqué dans une boucle infinie. -Essayons cela : +Essayons cela : -L'une des utilisations d'un `loop` est de réessayer une opération qui peut -échouer, comme vérifier si un processus a terminé son travail. Cependant, vous +L'une des utilisations d'une boucle `loop` est de réessayer une opération qui +peut échouer, comme vérifier si une tâche a terminé son travail. Cependant, vous aurez peut-être besoin de passer le résultat de l'opération au reste de votre -code. Pour faire ainsi, vous pouvez ajouter la valeur que vous voulez retourner -après l'expression `break` que vous utilisez pour stopper la boucle; cette +code. Pour ce faire, vous pouvez ajouter la valeur que vous voulez retourner +après l'expression `break` que vous utilisez pour stopper la boucle ; cette valeur sera retournée de la boucle pour que vous puissiez l'utiliser, comme ci-dessous : @@ -815,11 +816,11 @@ print the value in `result`, which in this case is 20. Avant la boucle, nous déclarons une variable avec le nom `compteur` et nous l'initialisons à `0`. Ensuite, nous déclarons une variable `resultat` pour -stocker la valeur retournée de la boucle. A chaque itération de la boucle, nous +stocker la valeur retournée de la boucle. À chaque itération de la boucle, nous ajoutons `1` à la variable `compteur`, et ensuite nous vérifions si le compteur est égal à `10`. Lorsque c'est le cas, nous utilisons le mot-clé `break` avec la valeur `compteur * 2`. Après la boucle, nous utilisons un point-virgule pour -terminer la déclaration qui assigne la valeur à `resultat`. Enfin, nous +terminer l'instruction qui assigne la valeur à `resultat`. Enfin, nous affichons la valeur de `resultat`, qui est 20 dans ce cas-ci. -Il est parfois utile pour un programme d'évaluer une condition dans une boucle. -Quand la condition est vraie, la boucle tourne. Quand la condition arrête -d'être vraie, le programme utilise `break`, ce qui arrête la boucle. Ce type de -boucle peut être implémenté en combinant `loop`, `if`, `else` et `break`; vous +Il est souvent utile pour un programme d'évaluer une condition dans une boucle. +Tant que la condition est vraie, la boucle tourne. Quand la condition arrête +d'être vraie, le programme appelle `break`, ce qui arrête la boucle. Ce type de +boucle peut être implémenté en combinant `loop`, `if`, `else` et `break` ; vous pouvez essayer de le faire, si vous voulez. -Cependant, cette utilisation est si fréquente que Rust a une instruction pour +Cependant, cette utilisation est si fréquente que Rust a une construction pour cela, intégrée dans le langage, qui s'appelle une boucle `while`. L'encart 3-3 utilise `while` : le programme va boucler trois fois, en décrémentant à chaque fois, et ensuite, après la boucle, il va afficher un message et se fermer. @@ -881,12 +882,12 @@ fn main() { let mut nombre = 3; while nombre != 0 { - println!("{} !", nombre); + println!("{} !", nombre); nombre -= 1; } - println!("DECOLLAGE !!!"); + println!("DÉCOLLAGE !!!"); } ``` @@ -904,9 +905,9 @@ This construct eliminates a lot of nesting that would be necessary if you used true, the code runs; otherwise, it exits the loop. --> -Cette instruction élimine beaucoup d'imbrications qui seraient nécessaires si +Cette construction élimine beaucoup d'imbrications qui seraient nécessaires si vous utilisiez `loop`, `if`, `else` et `break`, et c'est aussi plus clair. Tant -que la condition est vraie, le code est exécuté; sinon, il quitte la boucle. +que la condition est vraie, le code est exécuté ; sinon, il quitte la boucle. -Vous pouvez utiliser l'instruction `while` pour itérer créer une boucle sur les +Vous pouvez utiliser la construction `while` pour itérer sur les éléments d'une collection, comme les tableaux. Par exemple, analysons l'encart 3-4. @@ -950,7 +951,7 @@ fn main() { let mut indice = 0; while indice < 5 { - println!("La valeur est : {}", a[indice]); + println!("La valeur est : {}", a[indice]); indice += 1; } @@ -962,8 +963,8 @@ fn main() { using a `while` loop --> -Encart 3-4 : boucle pour chaque élément d'une collection en -utilisant une boucle `while` +Encart 3-4 : itération sur les éléments d'une collection +en utilisant une boucle `while` -Ici, le code va compter à partir du nombre d'éléments dans le tableau. Il -commence à l'indice `0`, et ensuite boucle jusqu'à ce qu'il atteigne l'indice +Ici, le code parcourt le tableau élément par élément. +Il commence à l'indice `0`, et ensuite boucle jusqu'à ce qu'il atteigne l'indice final du tableau (ce qui correspond au moment où la condition `index < 5` n'est plus vraie). Exécuter ce code va afficher chaque élément du tableau : @@ -996,11 +997,11 @@ $ cargo run Compiling loops v0.1.0 (file:///projects/loops) Finished dev [unoptimized + debuginfo] target(s) in 0.32 secs Running `target/debug/loops` -La valeur est : 10 -La valeur est : 20 -La valeur est : 30 -La valeur est : 40 -La valeur est : 50 +La valeur est : 10 +La valeur est : 20 +La valeur est : 30 +La valeur est : 40 +La valeur est : 50 ``` -Toutes les cinq valeurs du tableau s'affichent dans le terminal, comme attendu. -Même si `indice` va avoir la valeur `5` à un moment, la boucle arrêtera de +Les cinq valeurs du tableau s'affichent toutes dans le terminal, comme attendu. +Même si `indice` va atteindre la valeur `5` à un moment, la boucle arrêtera de s'exécuter avant d'essayer de récupérer une sixième valeur du tableau. -Mais cette pratique pousse à l'erreur; nous pourrions faire paniquer le -programme si l'indice est incorrect. Aussi, c'est lent, car le compilateur -ajoute du code d'exécution pour effectuer des vérifications sur chaque élément à -chaque itération de la boucle. +Mais cette approche pousse à l'erreur ; nous pourrions faire paniquer le +programme si l'indice est trop grand. De plus, c'est lent, car le compilateur +ajoute du code à l'exécution pour effectuer des vérifications sur chaque élément +à chaque itération de la boucle. -Encart 3-5 : itérer pour chaque élément d'une collection +Encart 3-5 : itérer sur chaque élément d'une collection en utilisant une boucle `for` -Par exemple, dans le code de l'encart 3-4, si vous enleviez un élément du +Par exemple, dans le code de l'encart 3-4, si vous enlevez un élément du tableau `a` mais que vous oubliez de mettre à jour la condition tel que `while indice < 4`, le code va paniquer. En utilisant la boucle `for`, vous n'aurez pas à vous rappeler de changer le code si vous changez le nombre de @@ -1106,13 +1107,13 @@ that generates all numbers in sequence starting from one number and ending before another number. --> -La sécurité et la concision de la boucle `for` en fait l'instruction de boucle +La sécurité et la concision de la boucle `for` en font la construction de boucle la plus utilisée avec Rust. Même dans des situations dans lesquelles vous voudriez exécuter du code plusieurs fois, comme l'exemple du décompte qui utilisait une boucle `while` dans l'encart 3-3, la plupart des Rustacés -utiliseraient une boucle `for`. Il faut pour cela utiliser un `Range`, qui est -un type fourni par la bibliothèque standard qui génère tous les nombres dans -l'ordre en commençant par un nombre et en finissant par un autre nombre. +utiliseraient une boucle `for`. Il faut pour cela utiliser un intervalle +`Range`, qui est un type fourni par la bibliothèque standard qui génère dans +l'ordre tous les nombres compris entre un certain nombre et un autre nombre. Voici ce que le décompte aurait donné en utilisant une boucle `for` et une autre -méthode que nous n'avons pas encore vu, `rev`, qui inverse le sens des données : +méthode que nous n'avons pas encore vue, `rev`, qui inverse l'intervalle : -Ce code est un peu plus sympa, non ? +Ce code est un peu plus sympa, non ? -Vous y êtes arrivé ! C'était un chapitre important : vous avez appris les +Vous y êtes arrivé ! C'était un chapitre important : vous avez appris les variables, les types scalaires et composés, les fonctions, les commentaires, les -expressions `if`, et les boucles ! Si vous voulez pratiquer un peu les concepts +expressions `if`, et les boucles ! Si vous voulez pratiquer un peu les concepts abordés dans ce chapitre, voici quelques programmes que vous pouvez essayer de créer : @@ -1180,9 +1181,9 @@ créer : taking advantage of the repetition in the song. --> -* Convertir des températures entre les Fahrenheit et les Celsius. +* Convertir des températures entre les degrés Fahrenheit et Celsius. * Générer le *n*-ième nombre de Fibonacci. -* Ecrire les paroles de la chanson de Noël, “Les Douze Jours de Noël”, en +* Afficher les paroles de la chanson de Noël *The Twelve Days of Christmas* en profitant de l'aspect répétitif de la chanson. -Quand vous serez prêt à aller plus loin, nous allons aborder une notion de Rust -qui n'existe *pas* dans les autres langages de programmation : la possession +Quand vous serez prêt à aller plus loin, nous aborderons une notion de Rust +qui n'existe *pas* dans les autres langages de programmation : la possession *(ownership)*. [comparing-the-guess-to-the-secret-number]: -ch02-00-guessing-game-tutorial.html#comparer-le-nombre-saisi-avec-le-nombre-secret +ch02-00-guessing-game-tutorial.html#comparer-le-nombre-saisi-au-nombre-secret [quitting-after-a-correct-guess]: ch02-00-guessing-game-tutorial.html#arrêter-le-programme-après-avoir-gagné From a5a5bf9d6ea5763a9110f727911a21da854b1d90 Mon Sep 17 00:00:00 2001 From: Aleru <41040598+Aleru@users.noreply.github.com> Date: Mon, 14 Oct 2019 12:56:15 -0400 Subject: [PATCH 089/117] Update ch07-05-separating-modules-into-different-files.md --- src/ch07-05-separating-modules-into-different-files.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ch07-05-separating-modules-into-different-files.md b/src/ch07-05-separating-modules-into-different-files.md index 0a455fb929..6b51859afd 100644 --- a/src/ch07-05-separating-modules-into-different-files.md +++ b/src/ch07-05-separating-modules-into-different-files.md @@ -76,7 +76,7 @@ that module. ## Summary -Rust lets you partition a package into multiple crates and a crate into modules +Rust lets you split a package into multiple crates and a crate into modules so you can refer to items defined in one module from another module. You can do this by specifying absolute or relative paths. These paths can be brought into scope with a `use` statement so you can use a shorter path for multiple uses of From f63a103270ec8416899675a9cdb1c5cf6d77a498 Mon Sep 17 00:00:00 2001 From: Sebastian Rasmussen Date: Mon, 17 Jun 2019 01:56:00 +0200 Subject: [PATCH 090/117] =?UTF-8?q?Consistently=20use=20quotation=20marks?= =?UTF-8?q?=20around=20=E2=80=9CHello,=20world!=E2=80=9D.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/ch00-00-introduction.md | 2 +- src/ch01-02-hello-world.md | 6 +++--- src/ch01-03-hello-cargo.md | 24 ++++++++++++------------ 3 files changed, 16 insertions(+), 16 deletions(-) diff --git a/src/ch00-00-introduction.md b/src/ch00-00-introduction.md index 7a37ee4ef4..86fe469f9c 100644 --- a/src/ch00-00-introduction.md +++ b/src/ch00-00-introduction.md @@ -104,7 +104,7 @@ chapters. In concept chapters, you’ll learn about an aspect of Rust. In projec chapters, we’ll build small programs together, applying what you’ve learned so far. Chapters 2, 12, and 20 are project chapters; the rest are concept chapters. -Chapter 1 explains how to install Rust, how to write a Hello, world! program, +Chapter 1 explains how to install Rust, how to write a “Hello, world!” program, and how to use Cargo, Rust’s package manager and build tool. Chapter 2 is a hands-on introduction to the Rust language. Here we cover concepts at a high level, and later chapters will provide additional detail. If you want to get diff --git a/src/ch01-02-hello-world.md b/src/ch01-02-hello-world.md index e82ba49670..82a545ab63 100644 --- a/src/ch01-02-hello-world.md +++ b/src/ch01-02-hello-world.md @@ -20,7 +20,7 @@ we suggest making a *projects* directory in your home directory and keeping all your projects there. Open a terminal and enter the following commands to make a *projects* directory -and a directory for the Hello, world! project within the *projects* directory. +and a directory for the “Hello, world!” project within the *projects* directory. For Linux, macOS, and PowerShell on Windows, enter this: @@ -86,7 +86,7 @@ program. That makes you a Rust programmer—welcome! ### Anatomy of a Rust Program -Let’s review in detail what just happened in your Hello, world! program. +Let’s review in detail what just happened in your “Hello, world!” program. Here’s the first piece of the puzzle: ```rust @@ -178,7 +178,7 @@ From here, you run the *main* or *main.exe* file, like this: $ ./main # or .\main.exe on Windows ``` -If *main.rs* was your Hello, world! program, this line would print `Hello, +If *main.rs* was your “Hello, world!” program, this line would print `Hello, world!` to your terminal. If you’re more familiar with a dynamic language, such as Ruby, Python, or diff --git a/src/ch01-03-hello-cargo.md b/src/ch01-03-hello-cargo.md index 34428e5f94..b40be39da5 100644 --- a/src/ch01-03-hello-cargo.md +++ b/src/ch01-03-hello-cargo.md @@ -6,9 +6,9 @@ such as building your code, downloading the libraries your code depends on, and building those libraries. (We call libraries your code needs *dependencies*.) The simplest Rust programs, like the one we’ve written so far, don’t have any -dependencies. So if we had built the Hello, world! project with Cargo, it would -only use the part of Cargo that handles building your code. As you write more -complex Rust programs, you’ll add dependencies, and if you start a project +dependencies. So if we had built the “Hello, world!” project with Cargo, it +would only use the part of Cargo that handles building your code. As you write +more complex Rust programs, you’ll add dependencies, and if you start a project using Cargo, adding dependencies will be much easier to do. Because the vast majority of Rust projects use Cargo, the rest of this book @@ -29,7 +29,7 @@ determine how to install Cargo separately. ### Creating a Project with Cargo Let’s create a new project using Cargo and look at how it differs from our -original Hello, world! project. Navigate back to your *projects* directory (or +original “Hello, world!” project. Navigate back to your *projects* directory (or wherever you decided to store your code). Then, on any operating system, run the following: @@ -99,10 +99,10 @@ fn main() { } ``` -Cargo has generated a Hello, world! program for you, just like the one we wrote -in Listing 1-1! So far, the differences between our previous project and the -project Cargo generates are that Cargo placed the code in the *src* directory, -and we have a *Cargo.toml* configuration file in the top directory. +Cargo has generated a “Hello, world!” program for you, just like the one we +wrote in Listing 1-1! So far, the differences between our previous project and +the project Cargo generates are that Cargo placed the code in the *src* +directory, and we have a *Cargo.toml* configuration file in the top directory. Cargo expects your source files to live inside the *src* directory. The top-level project directory is just for README files, license information, @@ -110,14 +110,14 @@ configuration files, and anything else not related to your code. Using Cargo helps you organize your projects. There’s a place for everything, and everything is in its place. -If you started a project that doesn’t use Cargo, as we did with the Hello, -world! project, you can convert it to a project that does use Cargo. Move the +If you started a project that doesn’t use Cargo, as we did with the “Hello, +world!” project, you can convert it to a project that does use Cargo. Move the project code into the *src* directory and create an appropriate *Cargo.toml* file. ### Building and Running a Cargo Project -Now let’s look at what’s different when we build and run the Hello, world! +Now let’s look at what’s different when we build and run the “Hello, world!” program with Cargo! From your *hello_cargo* directory, build your project by entering the following command: @@ -237,7 +237,7 @@ you’ve learned how to: * Install the latest stable version of Rust using `rustup` * Update to a newer Rust version * Open locally installed documentation -* Write and run a Hello, world! program using `rustc` directly +* Write and run a “Hello, world!” program using `rustc` directly * Create and run a new project using the conventions of Cargo This is a great time to build a more substantial program to get used to reading From 27e741b227b6b946a1498ecc9d9dd1bff5819b82 Mon Sep 17 00:00:00 2001 From: Sebastian Rasmussen Date: Mon, 17 Jun 2019 01:56:43 +0200 Subject: [PATCH 091/117] Clarify that it is not the installer that contains the documentation. --- src/ch01-01-installation.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/ch01-01-installation.md b/src/ch01-01-installation.md index 9061389e6d..d7659ebab8 100644 --- a/src/ch01-01-installation.md +++ b/src/ch01-01-installation.md @@ -126,9 +126,9 @@ resources include [the Users forum][users] and [Stack Overflow][stackoverflow]. ### Local Documentation -The installer also includes a copy of the documentation locally, so you can -read it offline. Run `rustup doc` to open the local documentation in your -browser. +The installation of Rust also includes a copy of the documentation locally, so +you can read it offline. Run `rustup doc` to open the local documentation in +your browser. Any time a type or function is provided by the standard library and you’re not sure what it does or how to use it, use the application programming interface From c427a676393d001edc82f1a54a3b8026abcf9690 Mon Sep 17 00:00:00 2001 From: Sebastian Rasmussen Date: Mon, 17 Jun 2019 02:26:29 +0200 Subject: [PATCH 092/117] Clarify meaning. --- src/ch02-00-guessing-game-tutorial.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ch02-00-guessing-game-tutorial.md b/src/ch02-00-guessing-game-tutorial.md index a992f192c0..2ecc1520ea 100644 --- a/src/ch02-00-guessing-game-tutorial.md +++ b/src/ch02-00-guessing-game-tutorial.md @@ -201,7 +201,7 @@ io::stdin().read_line(&mut guess) .expect("Failed to read line"); ``` -If we hadn’t listed the `use std::io` line at the beginning of the program, we +If we hadn’t put the `use std::io` line at the beginning of the program, we could have written this function call as `std::io::stdin`. The `stdin` function returns an instance of [`std::io::Stdin`][iostdin], which is a type that represents a handle to the standard input for your terminal. From 94e6df28d9068e806c17e3a283d2740718e6f8ea Mon Sep 17 00:00:00 2001 From: Sebastian Rasmussen Date: Sun, 23 Jun 2019 11:07:01 +0200 Subject: [PATCH 093/117] Improve wording. Especially the word "other" in this sentence is unclear, "other" than what/which? --- src/ch03-02-data-types.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/ch03-02-data-types.md b/src/ch03-02-data-types.md index 228e4316b2..d2eeea65b9 100644 --- a/src/ch03-02-data-types.md +++ b/src/ch03-02-data-types.md @@ -228,9 +228,9 @@ primitive compound types: tuples and arrays. #### The Tuple Type -A tuple is a general way of grouping together some number of other values -with a variety of types into one compound type. Tuples have a fixed length: -once declared, they cannot grow or shrink in size. +A tuple is a general way of grouping together a number of values with a variety +of types into one compound type. Tuples have a fixed length: once declared, +they cannot grow or shrink in size. We create a tuple by writing a comma-separated list of values inside parentheses. Each position in the tuple has a type, and the types of the From 9fd678a9f28b010ea9a7edde13a0e8ff437f617c Mon Sep 17 00:00:00 2001 From: Sebastian Rasmussen Date: Sun, 23 Jun 2019 11:15:23 +0200 Subject: [PATCH 094/117] Clarification. --- src/ch03-02-data-types.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/ch03-02-data-types.md b/src/ch03-02-data-types.md index d2eeea65b9..4bd7091052 100644 --- a/src/ch03-02-data-types.md +++ b/src/ch03-02-data-types.md @@ -286,8 +286,8 @@ fn main() { ``` This program creates a tuple, `x`, and then makes new variables for each -element by using their index. As with most programming languages, the first -index in a tuple is 0. +element by using their respective indices. As with most programming languages, +the first index in a tuple is 0. #### The Array Type From 6598d3abac05ed1d0c45db92466ea49346d05e40 Mon Sep 17 00:00:00 2001 From: Sebastian Rasmussen Date: Sun, 23 Jun 2019 11:26:10 +0200 Subject: [PATCH 095/117] Avoid mixing up the words elements and array/items. --- src/ch03-02-data-types.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/ch03-02-data-types.md b/src/ch03-02-data-types.md index 4bd7091052..482e69f73f 100644 --- a/src/ch03-02-data-types.md +++ b/src/ch03-02-data-types.md @@ -318,7 +318,7 @@ vector. Chapter 8 discusses vectors in more detail. An example of when you might want to use an array rather than a vector is in a program that needs to know the names of the months of the year. It’s very unlikely that such a program will need to add or remove months, so you can use -an array because you know it will always contain 12 items: +an array because you know it will always contain 12 elements: ```rust let months = ["January", "February", "March", "April", "May", "June", "July", @@ -334,7 +334,7 @@ let a: [i32; 5] = [1, 2, 3, 4, 5]; ``` Here, `i32` is the type of each element. After the semicolon, the number `5` -indicates the element contains five items. +indicates the array contains five elements. Writing an array’s type this way looks similar to an alternative syntax for initializing an array: if you want to create an array that contains the same From 83814221d660a2261ae02c28cc08f71c9feab003 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=ABl=20J=2E=20Pr=C3=A9sent?= <36854931+joeljpresent@users.noreply.github.com> Date: Thu, 17 Oct 2019 12:08:14 +0200 Subject: [PATCH 096/117] Proofread ch04-00 --- FRENCH/src/ch04-00-understanding-ownership.md | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/FRENCH/src/ch04-00-understanding-ownership.md b/FRENCH/src/ch04-00-understanding-ownership.md index 0630cfb7a9..73dbfae0c1 100644 --- a/FRENCH/src/ch04-00-understanding-ownership.md +++ b/FRENCH/src/ch04-00-understanding-ownership.md @@ -12,9 +12,9 @@ talk about ownership as well as several related features: borrowing, slices, and how Rust lays data out in memory. --> -La possession est la fonctionnalité la remarquable de Rust, et elle permet à -Rust de garantir la sécurité de la mémoire sans avoir besoin d'un -ramasse-miettes. Par conséquent, il est important de comprendre comment la -possession fonctionne avec Rust. Dans ce chapitre, nous aborderons la -possession, ainsi que d'autres fonctionnalités associées : l'emprunt, les -slices, et comprendre comment Rust conserve les données dans la mémoire. +La possession (*ownership*) est la fonctionnalité la plus remarquable de Rust, +et elle permet à Rust de garantir la sécurité de la mémoire sans avoir besoin +d'un ramasse-miettes (*garbage collector*). Par conséquent, il est important de +comprendre comment la possession fonctionne en Rust. Dans ce chapitre, nous +aborderons la possession, ainsi que d'autres fonctionnalités associées : +l'emprunt, les *slices* et la façon dont Rust agence les données en mémoire. From 680ecd0b45298c031e8d79526707768258d1009f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=ABl=20J=2E=20Pr=C3=A9sent?= <36854931+joeljpresent@users.noreply.github.com> Date: Thu, 17 Oct 2019 15:17:31 +0200 Subject: [PATCH 097/117] Translating ch05-01 --- FRENCH/src/SUMMARY.md | 1 + FRENCH/src/ch05-01-defining-structs.md | 713 +++++++++++++++++++++++++ 2 files changed, 714 insertions(+) create mode 100644 FRENCH/src/ch05-01-defining-structs.md diff --git a/FRENCH/src/SUMMARY.md b/FRENCH/src/SUMMARY.md index 065c52e2c5..9c8e956078 100644 --- a/FRENCH/src/SUMMARY.md +++ b/FRENCH/src/SUMMARY.md @@ -22,3 +22,4 @@ - [Les structures de contrôle](ch03-05-control-flow.md) - [Utiliser les structures pour structurer des données apparentées](ch05-00-structs.md) + - [Définir et instancier des structures](ch05-01-defining-structs.md) diff --git a/FRENCH/src/ch05-01-defining-structs.md b/FRENCH/src/ch05-01-defining-structs.md new file mode 100644 index 0000000000..004393e59e --- /dev/null +++ b/FRENCH/src/ch05-01-defining-structs.md @@ -0,0 +1,713 @@ + + +## Définir et instancier des structures + + + +Les structures sont similaires aux tuples, qu'on a abordés au chapitre 3. +Comme pour les tuples, les morceaux d'une structure peuvent être de types +différents. Contrairement aux tuples, on nomme chaque morceau de données pour +expliciter le rôle de chaque valeur. En conséquence de ces noms, les structures +sont plus flexibles que les tuples : on n'a pas à se fier à l'ordre des données +pour spécifier ou accéder aux valeurs d'une instance. + + + +Pour définir une structure, on tape le mot-clé `struct` et on nomme la structure +tout entière. Le nom d'une structure devrait décrire l'importance des morceaux +de données regroupés. Puis, entre des accolades, on définit le nom et le type de +chaque morceau de données, qu'on appelle un *champ*. Par exemple, l'encart 5-1 +montre une structure qui stocke des informations à propos d'un compte +d'utilisateur. + + + +```rust +struct Utilisateur { + pseudo: String, + email: String, + nombre_de_connexions: u64, + actif: bool, +} +``` + + + +Encart 5-1 : La définition d'une +structure `Utilisateur` + + + +Pour utiliser une structure après l'avoir définie, on crée une *instance* de +cette structure en indiquant des valeurs concrètes pour chacun des champs. +On crée une instance en énonçant le nom de la structure puis en ajoutant des +accolades qui contiennent des paires `clé: valeur`, où les clés sont les noms +des champs et les valeurs sont les données que l'on souhaite stocker dans ces +champs. Il n'est pas nécessaire de spécifier les champs dans le même ordre qu'on +les a déclarés dans la structure. En d'autres termes, la définition de la +structure forme un gabarit pour le type, et les instances remplissent ce gabarit +avec des données en particulier pour créer des valeurs de ce type. Par exemple, +on peut déclarer un utilisateur en particulier comme dans l'encart 5-2. + + + +```rust +# struct Utilisateur { +# pseudo: String, +# email: String, +# nombre_de_connexions: u64, +# actif: bool, +# } +# +let utilisateur1 = Utilisateur { + email: String::from("quelquun@example.com"), + pseudo: String::from("pseudoquelconque123"), + actif: true, + nombre_de_connexions: 1, +}; +``` + + + +Encart 5-2 : Création d'une instance de +la structure `Utilisateur` + + + +Pour obtenir une valeur spécifique depuis une structure, on utilise la notation +avec un point. Si nous voulions seulement l'adresse e-mail de cet utilisateur, +on pourrait utiliser `utilisateur1.email` partout où on voudrait utiliser cette +valeur. Si l'instance est mutable, on peut changer une valeur en utilisant la +notation avec un point et en assignant une valeur à un champ en particulier. +L'encart 5-3 montre comment changer la valeur du champ `email` d'une instance +mutable de `Utilisateur`. + + + +```rust +# struct Utilisateur { +# pseudo: String, +# email: String, +# nombre_de_connexions: u64, +# actif: bool, +# } +# +let mut utilisateur1 = Utilisateur { + email: String::from("quelquun@example.com"), + pseudo: String::from("pseudoquelconque123"), + actif: true, + nombre_de_connexions: 1, +}; + +utilisateur1.email = String::from("unautremail@example.com"); +``` + + + +Encart 5-3 : Changement de la valeur du champ +`email` d'une instance de `Utilisateur` + + + +À noter que l'instance tout entière doit être mutable ; Rust ne nous permet pas +de marquer seulement certains champs comme mutables. Comme pour toute +expression, nous pouvons construire une nouvelle instance de la structure comme +dernière expression du corps d'une fonction pour retourner implicitement cette +nouvelle instance. + + + +L'encart 5-4 montre une fonction `creer_utilisateur` qui renvoie une instance +de `Utilisateur` avec une adresse e-mail et un pseudo donnés. Le champ `actif` +prend la valeur `true` et le `nombre_de_connexions` prend la valeur `1`. + + + +```rust +# struct Utilisateur { +# pseudo: String, +# email: String, +# nombre_de_connexions: u64, +# actif: bool, +# } +# +fn creer_utilisateur(email: String, pseudo: String) -> Utilisateur { + Utilisateur { + email: email, + pseudo: pseudo, + actif: true, + nombre_de_connexions: 1, + } +} +``` + + + +Encart 5-4 : Une fonction `creer_utilisateur` qui prend +en entrée une adresse e-mail et un pseudo et retourne une instance +de `Utilisateur` + + + +Il est logique de nommer les paramètres de fonction avec le même nom que les +champs de la structure, mais devoir répéter les noms de variables et de champs +`email` et `pseudo` est un peu pénible. Si la structure avait plus de champs, +répéter chaque nom serait encore plus fatigant. Heureusement, il existe un +raccourci pratique ! + + + +### Utiliser le raccourci d'initialisation des champs lorsque les variables et les champs ont le même nom + + + +Puisque les noms de paramètres et les noms de champs de la structure sont +exactement les mêmes dans l'encart 5-4, on peut utiliser la syntaxe de +*raccourci d'initialisation des champs* pour réécrire `creer_utilisateur` de +sorte qu'elle se comporte exactement de la même façon sans avoir à répéter +les mots `email` et `pseudo`, comme le montre l'encart 5-5. + + + +```rust +# struct Utilisateur { +# pseudo: String, +# email: String, +# nombre_de_connexions: u64, +# actif: bool, +# } +# +fn creer_utilisateur(email: String, pseudo: String) -> Utilisateur { + Utilisateur { + email, + pseudo, + actif: true, + nombre_de_connexions: 1, + } +} +``` + + + +Encart 5-5 : Une fonction `creer_utilisateur` qui utilise +le raccourci d'initialisation des champs parce que les paramètres `email` et +`pseudo` ont le même nom que les champs de la structure + + + +Ici, on crée une nouvelle instance de la structure `Utilisateur`, qui possède +un champ nommé `email`. On veut donner au champ `email` la valeur du paramètre +`email` de la fonction `creer_utilisateur`. +Puisque le champ `email` et le paramètre `email` possèdent le même nom, +on a uniquement besoin d'écrire `email` plutôt que `email: email`. + + + +### Créer des instances à partir d'autres instances avec la syntaxe de mise à jour de structure + + + +Il est souvent utile de créer une nouvelle instance de structure qui utilise la +plupart des valeurs d'une ancienne instance tout en en changeant certaines. +On utilisera la *syntaxe de mise à jour de structure* pour ce faire. + + + +Tout d'abord, l'encart 5-6 nous montre comment créer une nouvelle instance de +`Utilisateur` dans `utilisateur2` sans la syntaxe de mise à jour de structure. +On donne de nouvelles valeurs à `email` et `pseudo` mais on utilise pour les +autres champs les mêmes valeurs que dans `utilisateur1` qu'on a créé à +l'encart 5-2. + + + +```rust +# struct Utilisateur { +# pseudo: String, +# email: String, +# nombre_de_connexions: u64, +# actif: bool, +# } +# +# let utilisateur1 = Utilisateur { +# email: String::from("quelquun@example.com"), +# pseudo: String::from("pseudoquelconque123"), +# actif: true, +# nombre_de_connexions: 1, +# }; +# +let utilisateur2 = Utilisateur { + email: String::from("quelquundautre@example.com"), + pseudo: String::from("autrepseudo567"), + actif: utilisateur1.actif, + nombre_de_connexions: utilisateur1.nombre_de_connexions, +}; +``` + + + +Encart 5-6 : Création d'une nouvelle instance de `User` +en utilisant certaines valeurs de `user1`. + + + +En utilisant la syntaxe de mise à jour de structure, on peut produire le même +effet avec moins de code, comme le montre l'encart 5-7. La syntaxe `..` indique +que les champs restants auxquels on ne donne pas de valeur explicite devraient +avoir la même valeur que dans l'instance donnée. + + + +```rust +# struct Utilisateur { +# pseudo: String, +# email: String, +# nombre_de_connexions: u64, +# actif: bool, +# } +# +# let utilisateur1 = Utilisateur { +# email: String::from("quelquun@example.com"), +# pseudo: String::from("pseudoquelconque123"), +# actif: true, +# nombre_de_connexions: 1, +# }; +# +let utilisateur2 = Utilisateur { + email: String::from("quelquundautre@example.com"), + pseudo: String::from("autrepseudo567"), + ..utilisateur1 +}; +``` + + + +Encart 5-7 : Utilisation de la syntaxe de mise à jour de +structure pour assigner de nouvelles valeurs à `email` et `pseudo` pour une +instance de `Utilisateur` tout en utilisant les autres valeurs des champs de +l'instance de la variable `utilisateur1` + + + +Le code dans l'encart 5-7 crée aussi une instance dans `utilisateur2` qui a une +valeur différente pour `email` et `pseudo` mais qui a les mêmes valeurs pour les +champs `actif` et `nombre_de_connexions` que `utilisateur1`. + + + +### Utilisation de structures tuples sans champ nommé pour créer des types différents + + + +On peut aussi définir des structures qui ressemblent à des tuples, appelées +*structures tuples*. La signification d'une structure tuple est donnée par son +nom. En revanche, ses champs ne sont pas nommés ; on ne précise que leurs types. +Les structures tuples sont utiles quand on veut donner un nom à un tuple pour +qu'il ait un type différent des autres tuples, mais que nommer chaque champ +comme dans une structure classique serait verbeux ou redondant. + + + +La définition d'une structure tuple commence par le mot-clé `struct` et le nom +de la structure suivis des types des champs du tuple. Par exemple, voici +comment définir et utiliser deux structures tuples nommées `Couleur` et +`Point` : + + + +```rust +struct Couleur(i32, i32, i32); +struct Point(i32, i32, i32); + +let noir = Couleur(0, 0, 0); +let origine = Point(0, 0, 0); +``` + + + +À noter que les valeurs `noir` et `origine` sont de types différents parce que +ce sont des instances de structures tuples différentes. Chaque structure que +l'on définit constitue son propre type, même si les champs au sein de la +structure ont les mêmes types. Par exemple, une fonction qui prend un paramètre +de type `Couleur` ne peut pas prendre un argument de type `Point` à la place, +bien que les deux types soient constitués de trois valeurs `i32`. En dehors de +ça, les instances de stuctures tuples se comportent comme des tuples : on peut +les déstructurer en morceaux individuels, on peut utiliser un `.` suivi de +l'indice pour accéder à une valeur individuelle, et ainsi de suite. + + + +### Les structures unitaires sans champs + + + +On peut aussi définir des structures qui n'ont pas de champs ! On les appelle +des *structures unitaires* parce qu'elles se comportent d'une façon analogue +au type unité `()`. Les structures unitaires peuvent être utiles quand on doit +implémenter un trait sur un type mais qu'on n'a pas de données à stocker dans +le type lui-même. Nous aborderons les traits au chapitre 10. + +> +> ### Possession des données d'une structure +> +> +> +> Dans la définition de la structure `Utilisateur` dans l'encart 5-1, nous +> avions utilisé le type possédé `String` plutôt que le type de *slice* de +> chaîne de caractères `&str`. Il s'agit d'un choix délibéré puisque nous +> voulons que les instances de cette structure possèdent toutes leurs données et +> que ces données soient valides tant que la structure tout entière est valide. +> +> +> +> Il est possible pour les structures de stocker des références à des données +> possédées par autre chose, mais cela nécessiterait d'utiliser des +> *durées de vie*, une fonctionnalité de Rust que nous aborderons au +> chapitre 10. Les durées de vie s'assurent que les données référencées par une +> structure sont valides aussi longtemps que la structure est valide aussi. +> Disons que vous essayiez de stocker une référence dans une structure sans +> indiquer de durées de vie, comme ceci, ce qui ne fonctionnera pas : +> +> +> +> Fichier : src/main.rs +> +> +> +> ```rust,ignore,does_not_compile +> struct Utilisateur { +> pseudo: &str, +> email: &str, +> nombre_de_connexions: u64, +> actif: bool, +> } +> +> fn main() { +> let utilisateur1 = Utilisateur { +> email: "quelquun@example.com", +> pseudo: "pseudoquelconque123", +> actif: true, +> nombre_de_connexions: 1, +> }; +> } +> ``` +> +> +> +> Le compilateur se plaindra qu'il a besoin de spécificateurs de durées de vie : +> +> ```text +> error[E0106]: missing lifetime specifier +> --> +> | +> 2 | username: &str, +> | ^ expected lifetime parameter +> +> error[E0106]: missing lifetime specifier +> --> +> | +> 3 | email: &str, +> | ^ expected lifetime parameter +> ``` +> +> +> +> Au chapitre 10, nous aborderons la façon de corriger ces erreurs pour qu'on +> puisse stocker des références dans des structures, mais pour le moment, nous +> corrigerons les erreurs comme celles-ci en utilisant des types possédés comme +> `String` plutôt que des références comme `&str`. From 24b3d8711371a724d34546878d2f27f077d192d4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=B0=A1=E7=85=92=E8=88=AA=20=28Jian=20Weihang=29?= Date: Tue, 22 Oct 2019 21:12:16 +0800 Subject: [PATCH 098/117] Update src/ch20-02-multithreaded.md Co-Authored-By: Steve Klabnik --- src/ch20-02-multithreaded.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ch20-02-multithreaded.md b/src/ch20-02-multithreaded.md index e80b05e0ce..649d34a0af 100644 --- a/src/ch20-02-multithreaded.md +++ b/src/ch20-02-multithreaded.md @@ -364,7 +364,7 @@ impl ThreadPool { ``` We still use the `()` after `FnOnce` because this `FnOnce` represents a closure -that takes no parameters and returns an unit type `()`. Just like function +that takes no parameters and returns the unit type `()`. Just like function definitions, the return type can be omitted from the signature, but even if we have no parameters, we still need the parentheses. From 729404a43fd1b6012b388acd0f01e1eb7a23851e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=ABl=20J=2E=20Pr=C3=A9sent?= <36854931+joeljpresent@users.noreply.github.com> Date: Thu, 24 Oct 2019 14:03:35 +0200 Subject: [PATCH 099/117] Proofread ch04-01 --- FRENCH/src/ch04-01-what-is-ownership.md | 409 ++++++++++++------------ FRENCH/src/img/trpl04-01.svg | 14 +- FRENCH/src/img/trpl04-02.svg | 24 +- FRENCH/src/img/trpl04-03.svg | 28 +- FRENCH/src/img/trpl04-04.svg | 24 +- 5 files changed, 252 insertions(+), 247 deletions(-) diff --git a/FRENCH/src/ch04-01-what-is-ownership.md b/FRENCH/src/ch04-01-what-is-ownership.md index b926171d7a..2f23a395d4 100644 --- a/FRENCH/src/ch04-01-what-is-ownership.md +++ b/FRENCH/src/ch04-01-what-is-ownership.md @@ -25,12 +25,12 @@ running. Tous les programmes doivent gérer la façon dont ils utilisent la mémoire lorsqu'ils s'exécutent. Certains langages ont un ramasse-miettes qui scrute -constamment la mémoire qui n'est plus utilisée pendant qu'il s'exécute; dans +constamment la mémoire qui n'est plus utilisée pendant qu'il s'exécute ; dans d'autres langages, le développeur doit explicitement allouer et libérer la mémoire. Rust adopte une troisième approche : la mémoire est gérée avec un système de possession qui repose sur un jeu de règles que le compilateur vérifie -au moment de la compilation. Il n'y a pas d'impact sur les performances pendant -l'exécution pour toutes les fonctionnalités de possession. +au moment de la compilation. Aucune des fonctionnalités de possession ne +ralentit votre programme à l'exécution. -Lorsque vous comprendrez la possession, vous aurez des base solide pour +Lorsque vous comprendrez la possession, vous aurez des bases solides pour comprendre les fonctionnalités qui font la particularité de Rust. Dans ce chapitre, vous allez apprendre la possession en pratiquant avec plusieurs exemples qui se concentrent sur une structure de données très courante : les @@ -126,23 +126,24 @@ chaînes de caractères. > ### La pile et le tas > -> Dans de nombreux langages, il n'est pas nécessaire de se préoccupper de la -> pile et du tas. Mais dans un système de langage de programmation comme -> Rust, si une donnée est sur la pile ou sur le tas influe le comportement du -> langage et explique pourquoi nous devons faire certains choix. Nous décrirons -> plus loin dans ce chapitre les différences entre la pile et le tas, voici -> donc une brève explication en attendant. +> Dans de nombreux langages, il n'est pas nécessaire de se préoccuper de la +> pile (*stack*) et du tas (*heap*). Mais dans un langage de programmation +> système comme Rust, qu'une donnée soit sur la pile ou sur le tas influe +> sur le comportement du langage et explique pourquoi nous devons faire certains +> choix. Nous décrirons plus loin dans ce chapitre comment la possession +> fonctionne vis-à-vis de la pile et du tas, voici donc une brève explication au +> préalable. > > La pile et le tas sont tous les deux des emplacements de la mémoire qui > sont à disposition de votre code lors de son exécution, mais sont organisés de -> façon différents. La pile enregistre les valeurs dans l'ordre qu'elle le +> façon différente. La pile enregistre les valeurs dans l'ordre qu'elle les > reçoit et enlève les valeurs dans l'autre sens. C'est ce que l'on appelle le > principe de *dernier entré, premier sorti*. C'est comme une pile d'assiettes : > quand vous ajoutez des nouvelles assiettes, vous les déposez sur le dessus de > la pile, et quand vous avez besoin d'une assiette, vous en prenez une sur le > dessus. Ajouter ou enlever des assiettes au milieu ou en bas ne serait pas -> aussi efficace ! Ajouter une donnée est ainsi appelé *déposer sur la pile* et -> en enlever une se dit *retirer de la pile*. +> aussi efficace ! Ajouter une donnée sur la pile se dit *empiler* et en retirer +> une se dit *dépiler*. > > Toutes les données stockées dans la pile doivent avoir une taille connue et > fixe. Les données avec une taille inconnue au moment de la compilation ou une @@ -151,53 +152,52 @@ chaînes de caractères. > demandez une certaine quantité d'espace mémoire. Le système d'exploitation va > trouver un emplacement dans le tas qui est suffisamment grand, va le marquer > comme étant en cours d'utilisation, et va retourner un *pointeur*, qui est -> l'adresse de cet emplacement. Cette procédure est appelée *affecter de la -> place sur le tas*, et parfois nous raccourcissons cette phrase à simplement -> *affectation*. Pousser des valeurs sur la pile n'est pas considéré comme -> une affectation. Comme le pointeur a une taille connue et fixe, nous pouvons -> stocker ce pointeur sur la pile, mais quand nous voulons la donnée souhaitée, -> nous avons devons suivre le pointeur. +> l'adresse de cet emplacement. Cette procédure est appelée *allocation sur le +> tas*, ce qu'on abrège parfois en *allocation* tout court. L'ajout de valeurs +> sur la pile n'est pas considéré comme une allocation. Comme le pointeur a une +> taille connue et fixe, on peut stocker ce pointeur sur la pile, mais quand on +> veut la vraie donnée, il faut suivre le pointeur. > -> C'est comme si vous vouliez manger à un restaurant. Quand vous entrez, vous +> C'est comme si vous vouliez manger au restaurant. Quand vous entrez, vous > indiquez le nombre de personnes dans votre groupe, et le personnel trouve une > table vide qui peut recevoir tout le monde, et vous y conduit. Si quelqu'un > dans votre groupe arrive en retard, il peut leur demander où vous êtes assis > pour vous rejoindre. > -> Déposer sur la pile est plus rapide qu'affecter sur le tas car le système +> Empiler sur la pile est plus rapide qu'allouer sur le tas car le système > d'exploitation ne va jamais avoir besoin de chercher un emplacement pour y -> stocker les nouvelles données; car c'est toujours au-dessus de la pile. En +> stocker les nouvelles données ; il le fait toujours au sommet de la pile. En > comparaison, allouer de la place sur le tas demande plus de travail, car le > système d'exploitation doit d'abord trouver un espace assez grand pour stocker -> les données et mettre à jour son suivi pour préparer la prochaine affectation. -> +> les données et mettre à jour son suivi pour préparer la prochaine allocation. +> > Accéder à des données dans le tas est plus lent que d'accéder aux données sur -> la pile car nous devons suivre un pointeur pour l'obtenir. Les processeurs +> la pile car nous devons suivre un pointeur pour les obtenir. Les processeurs > modernes sont plus rapides s'ils se déplacent moins dans la mémoire. Pour -> continuer avec notre analogie, imaginez une serveur dans un restaurant qui +> continuer avec notre analogie, imaginez un serveur dans un restaurant qui > prend les commandes de nombreuses tables. C'est plus efficace de récupérer > toutes les commandes à une seule table avant de passer à la table suivante. > Prendre une commande à la table A, puis prendre une commande à la table B, > puis ensuite une autre à la table A, puis une autre à la table B serait un > processus bien plus lent. De la même manière, un processeur sera plus efficace -> dans sa tâche s'il travaille sur des données qui sont proches l'une de l'autre -> (comme c'est le cas sur la pile) plutôt que si elles sont plus éloignées -> (comme cela peut être le cas sur le tas). Affecter une grande quantité -> d'espace sur le tas peut aussi prendre beaucoup de temps. +> dans sa tâche s'il travaille sur des données qui sont proches les unes des +> autres (comme c'est le cas sur la pile) plutôt que si elles sont plus +> éloignées (comme cela peut être le cas sur le tas). Allouer une grande +> quantité de mémoire sur le tas peut aussi prendre beaucoup de temps. > -> Quand notre code utilise une fonction, les valeurs envoyées à la fonction +> Quand notre code utilise une fonction, les valeurs passées à la fonction > (incluant, potentiellement, des pointeurs de données sur le tas) et les > variables locales à la fonction sont déposées sur la pile. Quand l'utilisation > de la fonction est terminée, ces données sont retirées de la pile. > > La possession nous aide à ne pas nous préoccuper de faire attention à quelles -> parties du code utilisent quelles de données sur le tas, de minimiser la +> parties du code utilisent quelles données sur le tas, de minimiser la > quantité de données en double sur le tas, ou encore de veiller à libérer les > données inutilisées sur le tas pour que nous ne soyons pas à court d'espace. > Quand vous aurez compris la possession, vous n'aurez plus besoin de vous -> préoccuper de la pile et du tas, mais savoir que la possession existe pour -> gérer les données du tas peut vous aider à comprendre pourquoi elle fonctionne -> de cette manière. +> préoccuper de la pile et du tas très souvent, mais savoir que la possession +> existe pour gérer les données du tas peut vous aider à comprendre pourquoi +> elle fonctionne de cette manière. -* Chaque valeur dans Rust a une variable qui s'appelle son *propriétaire*. -* Il ne peut y avoir qu'un seul propriétaire au même moment. -* Quand le propriétaire sort de la portée, la valeur sera supprimée. +* Chaque valeur en Rust a une variable qui s'appelle son *propriétaire*. +* Il ne peut y avoir qu'un seul propriétaire à la fois. +* Quand le propriétaire sortira de la portée, la valeur sera supprimée. -Nous avons déjà vu un exemple dans le programme Rust du chapitre 2. Maintenant +Nous avons déjà vu un exemple de programme Rust au chapitre 2. Maintenant que nous avons vu la syntaxe Rust de base, nous n'allons plus ajouter tout le -code autour de `fn main() {` dans des exemples, donc si vous voulez reproduire +code du style `fn main() {` dans les exemples, donc si vous voulez reproduire les exemples, vous devrez les mettre manuellement dans une fonction `main`. Par conséquent, nos exemples seront plus concis, nous permettant de nous concentrer sur les détails de la situation plutôt que sur du code normalisé. @@ -252,8 +252,8 @@ have a variable that looks like this: --> Pour le premier exemple de possession, nous allons analyser la *portée* de -certaines variables. Une portée est une zone dans un programme dans lequel un -élément est en vigueur. Imaginons que nous avons la variable suivante : +certaines variables. Une portée est une zone dans un programme dans laquelle un +élément est en vigueur. Imaginons que nous ayons la variable suivante : ```rust let s = "hello"; @@ -266,11 +266,11 @@ which it’s declared until the end of the current *scope*. Listing 4-1 has comments annotating where the variable `s` is valid. --> -La variable `s` fait référence à une chaîne de caractères pure, où la valeur de -la chaîne est codée en dur dans notre programme. La variable est en vigueur à -partir du point où elle est déclarée jusqu'à la fin de la *portée* actuelle. -L'encart 4-1 a des commentaires pour indiquer quand la variable `s` est en -vigueur : +La variable `s` fait référence à un littéral de chaîne de caractères, où la +valeur de la chaîne est codée en dur dans notre programme. La variable est en +vigueur à partir du moment où elle est déclarée jusqu'à la fin de la *portée* +actuelle. L'encart 4-1 a des commentaires pour indiquer quand la variable `s` +est en vigueur : ```rust -{ // s n'est pas en vigueur ici, elle n'est pas encore déclarée +{ // s n'est pas en vigueur ici, elle n'est pas encore déclarée let s = "hello"; // s est en vigueur à partir de ce point // on fait des choses avec s ici -} // cette portée est maintenant terminée, et s n'est plus en vigueur +} // cette portée est maintenant terminée, et s n'est plus en vigueur ``` -Encart 4-1 : une variable et la portée dans laquelle elle +Encart 4-1 : Une variable et la portée dans laquelle elle est en vigueur. Pour illustrer les règles de la possession, nous avons besoin d'un type de -donnée qui est plus complexe que ceux que nous avons rencontré dans la section +donnée qui est plus complexe que ceux que nous avons rencontrés dans la section [“Types de données”][data-types] du chapitre 3. Les types que -nous avons vu précédemment sont tous stockées sur la pile et sont retirés de la -pile quand ils sortent de la portée, mais nous voulons expérimenter les données -stockées sur le tas et découvrir comment Rust sait quand il doit nettoyer ces +nous avons vus précédemment sont tous stockés sur la pile et sont retirés de la +pile quand ils sortent de la portée, mais nous voulons expérimenter le stockage +de données sur le tas et découvrir comment Rust sait quand il doit nettoyer ces données. Nous allons utiliser ici `String` pour l'exemple et nous concentrer sur les -éléments de `String` qui sont liés à la possession. Ces caractéristiques -s'appliquent également à d'autres types de données complexes, qu'elles soient -fournies par la bibliothèque standard ou qu'elle soit créées par vous. Nous +caractéristiques de `String` qui sont liées à la possession. Ces aspects +s'appliquent également à d'autres types de données complexes, qu'ils soient +fournis par la bibliothèque standard ou qu'ils soient créés par vous. Nous verrons `String` plus en détail dans le chapitre 8. -Nous avons déjà vu les chaînes de caractères pures, quand une valeur de chaîne -est codée en dur dans notre programme. Les chaînes de caractères pures sont -pratiques, mais elles ne conviennent pas toujours à tous les cas où vous voulez -utiliser du texte. Une des raisons est qu'elle est immuable. Une autre raison -est qu'on ne connait pas forcément le contenu des chaînes de caractères quand +Nous avons déjà vu les littéraux de chaînes de caractères, quand une valeur de +chaîne est codée en dur dans notre programme. Les littéraux de chaînes sont +pratiques, mais ils ne conviennent pas toujours à tous les cas où on veut +utiliser du texte. Une des raisons est qu'ils sont immuables. Une autre raison +est qu'on ne connaît pas forcément le contenu des chaînes de caractères quand nous écrivons notre code : par exemple, comment faire si nous voulons récupérer du texte saisi par l'utilisateur et l'enregistrer ? Pour ces cas-ci, Rust a un -second type de chaîne de caractères, `String`. Ce type est affecté sur le tas et +second type de chaîne de caractères, `String`. Ce type est alloué sur le tas et est ainsi capable de stocker une quantité de texte qui nous est inconnue au -moment de la compilation. Vous pouvez créer un `String` à partir d'une chaîne -de caractères pure en utilisant la fonction `from`, comme ceci : +moment de la compilation. Vous pouvez créer une `String` à partir d'un littéral +de chaîne de caractères en utilisant la fonction `from`, comme ceci : ```rust let s = String::from("hello"); @@ -398,8 +398,11 @@ Module Tree”][paths-module-tree] du chapitre 5 et +lorsque nous aborderons les espaces de noms dans la section +[“Les chemins pour désigner un élément dans l'arborescence de module”][paths-module-tree] +du chapitre 7. Donc, quelle est la différence ici ? Pourquoi `String` peut être mutable, mais -pourquoi les chaînes de caractères pures ne peuvent pas l'être ? La différence +pourquoi les littéraux de chaînes ne peuvent pas l'être ? La différence se trouve dans la façon dont ces deux types travaillent avec la mémoire. -### Mémoire et affectation +### Mémoire et allocation -Dans le cas d'une chaîne de caractères pure, nous connaissons le contenu au -moment de la compilation donc le texte est codé en dur directement dans -l'exécutable final. Ceci fait que ces chaînes de caractères pures sont -performantes et rapides. Mais ces caractéristiques viennent de leur immuabilité. -Malheureusement, nous ne pouvons pas stocker un blob de mémoire dans le binaire -pour chaque morceau de texte qui n'a pas de taille connue au moment de la -compilation et dont la taille pourrait changer pendant l'exécution de ce +Dans le cas d'un littéral de chaîne de caractères, nous connaissons le contenu +au moment de la compilation donc le texte est codé en dur directement dans +l'exécutable final. Voilà pourquoi ces littéraux de chaînes de caractères sont +performants et rapides. Mais ces caractéristiques viennent de leur immuabilité. +Malheureusement, on ne peut pas accorder une grosse région de mémoire dans le +binaire pour chaque morceau de texte qui n'a pas de taille connue au moment de +la compilation et dont la taille pourrait changer pendant l'exécution de ce programme. -Ceci est un cas naturel pour lequel nous devons rendre la mémoire de notre +Il y a un moment naturel où nous devons rendre la mémoire de notre `String` au système d'exploitation : quand `s` sort de la portée. Quand une -variable sort de la portée, Rust utilise une fonction spéciale pour nous. Cette -fonction s'appelle `drop`, et c'est dans celle-ci que l'auteur du `String` a pu +variable sort de la portée, Rust appelle une fonction spéciale pour nous. Cette +fonction s'appelle `drop`, et c'est dans celle-ci que l'auteur de `String` a pu mettre le code pour libérer la mémoire. Rust appelle automatiquement `drop` à l'accolade fermante `}`. @@ -565,10 +568,10 @@ l'accolade fermante `}`. > patterns. --> -> Remarque : dans du C++, cette façon de libérer des ressources à la fin de la -> durée de vie d'un élément est parfois appelé *l'acquisition d'une ressource +> Remarque : en C++, cette façon de libérer des ressources à la fin de la +> durée de vie d'un élément est parfois appelée *l'acquisition d'une ressource > est une initialisation (RAII)*. La fonction `drop` de Rust vous sera familière -> si vous avez déjà utilisé une configuration en RAII. +> si vous avez déjà utilisé des techniques de RAII. -Cette façon de faire a un impact profond sur la façon dont le code de Rust est +Cette façon de faire a un impact profond sur la façon dont le code Rust est écrit. Cela peut sembler simple dans notre cas, mais le comportement du code -peut être surprenant dans des situations plus compliquées lorsque nous voulons -avoir plusieurs variables avec des données que nous avons affecté sur le tas. -Examinons une de ces situations dès à présent. +peut être surprenant dans des situations plus compliquées où nous voulons +avoir plusieurs variables utilisant des données que nous avons affectées sur le +tas. Examinons une de ces situations dès à présent. -#### Les interactions entre les variables et les données : les déplacements +#### Les interactions entre les variables et les données : le déplacement Plusieurs variables peuvent interagir avec les mêmes données de différentes -manières avec Rust. Regardons un exemple avec un entier dans l'encart 4-2 : +manières en Rust. Regardons un exemple avec un entier dans l'encart 4-2 : ```rust let x = 5; @@ -607,7 +610,7 @@ let y = x; to `y` --> -Encart 4-2 : assigner l'entier de la variable `x` à `y` +Encart 4-2 : Assigner l'entier de la variable `x` à `y` -Nous pouvons probablement deviner ce qui va se passer : “Assigner la valeur `5` -à `x`; ensuite faire une copie de cette valeur de `x` et l'assigner à `y`.” Nous -avons maintenant deux variables, `x` et `y`, et chacune vaut `5`. C'est +Nous pouvons probablement deviner ce que ce code fait : “Assigner la valeur `5` +à `x` ; ensuite faire une copie de cette valeur de `x` et l'assigner à `y`.” +Nous avons maintenant deux variables, `x` et `y`, et chacune vaut `5`. C'est effectivement ce qui se passe, car les entiers sont des valeurs simples avec une taille connue et fixée, et ces deux valeurs `5` sont stockées sur la pile. @@ -655,10 +658,10 @@ heap that holds the contents. --> Regardons l'illustration 4-1 pour découvrir ce qui arrive à `String` sous le -capot. Un `String` est constitué de trois éléments, présents sur la gauche : un -pointeur vers la mémoire qui contient le contenu de la chaîne de caractères, une -taille, et une capacité. Ce groupe de données est stocké sur la pile. A droite, -nous avons la mémoire sur le tas qui contient les données. +capot. Une `String` est constituée de trois éléments, présents sur la gauche : +un pointeur vers la mémoire qui contient le contenu de la chaîne de caractères, +une taille, et une capacité. Ce groupe de données est stocké sur la pile. À +droite, nous avons la mémoire sur le tas qui contient les données. String in memory @@ -667,8 +670,8 @@ nous avons la mémoire sur le tas qui contient les données. holding the value `"hello"` bound to `s1` --> -Illustration 4-1 : représentation d'un `String` dans la -mémoire qui contient la valeur `"hello"` assignée à `s1`. +Illustration 4-1 : Représentation en mémoire d'une +`String` qui contient la valeur `"hello"` assignée à `s1`. -La taille est combien de mémoire, en octets, le contenu du `String` utilise -actuellement. La capacité est la quantité totale de mémoire, en octets, que le -`String` a reçu du système d'exploitation. La différence entre la taille et la -capacité est importante, mais pas pour notre exemple, donc pour l'instant, ce -n'est pas grave d'ignorer la capacité. +La taille est la quantité de mémoire, en octets, que le contenu de la `String` +utilise actuellement. La capacité est la quantité totale de mémoire, en octets, +que la `String` a reçue du système d'exploitation. La différence entre la taille +et la capacité est importante, mais pas pour notre exemple, donc pour l'instant, +ce n'est pas grave d'ignorer la capacité. -Quand nous assignons `s1` à `s2`, les données de `String` sont copiées, ce qui -veut dire que nous copions le pointeur, la taille, et la capacité qui sont -stockés sur la pile. Nous ne copions pas les données stockées sur le tas sur -lequel le pointeur se réfère. Autrement dit, la représentation des données dans -la mémoire ressemble à l'illustration 4-2. +Quand nous assignons `s1` à `s2`, les données de la `String` sont copiées, ce +qui veut dire que nous copions le pointeur, la taille et la capacité qui sont +stockés sur la pile. Nous ne copions pas les données stockées sur le tas +auxquelles le pointeur se réfère. Autrement dit, la représentation des données +dans la mémoire ressemble à l'illustration 4-2. s1 and s2 pointing to the same value @@ -704,8 +707,8 @@ la mémoire ressemble à l'illustration 4-2. that has a copy of the pointer, length, and capacity of `s1` --> -Illustration 4-2 : représentation dans la mémoire de la -variable `s2` qui est une copie du pointeur, de la taille et de la capacité de +Illustration 4-2 : Représentation en mémoire de la +variable `s2` qui a une copie du pointeur, de la taille et de la capacité de `s1` -Cette représentation *n'est pas* comme l'illustration 4-3, qui serait la mémoire -si Rust avait aussi copié les données sur le tas. Si Rust faisait ceci, +Cette représentation *n'est pas* comme l'illustration 4-3, qui représenterait la +mémoire si Rust avait aussi copié les données sur le tas. Si Rust faisait ceci, l'opération `s2 = s1` pourrait potentiellement être très coûteuse en termes de performances d'exécution si les données sur le tas étaient volumineuses. @@ -727,7 +730,7 @@ performances d'exécution si les données sur le tas étaient volumineuses. do if Rust copied the heap data as well --> -Illustration 4-3 : une autre possibilité de ce que +Illustration 4-3 : Une autre possibilité de ce que pourrait faire `s2 = s1` si Rust copiait aussi les données du tas -Précédemment, nous avons dit que quand une variable sort de la portée, Rust +Précédemment, nous avons dit que quand une variable sortait de la portée, Rust appelait automatiquement la fonction `drop` et nettoyait la mémoire sur le tas -utilisé par cette variable. Mais l'illustration 4-2 montre que les deux -pointeurs de données pointaient au même endroit. C'est un problème : quand +allouée pour cette variable. Mais l'illustration 4-2 montre que les deux +pointeurs de données pointeraient au même endroit. C'est un problème : quand `s2` et `s1` sortent de la portée, elles vont essayer toutes les deux de libérer la même mémoire. C'est ce qu'on appelle une erreur de *double libération* et c'est un des bogues de sécurité de mémoire que nous avons -mentionné précédemment. Libérer la mémoire deux fois peut mener à des +mentionnés précédemment. Libérer la mémoire deux fois peut mener à des corruptions de mémoire, ce qui peut potentiellement mener à des vulnérabilités de sécurité. @@ -761,9 +764,9 @@ use `s1` after `s2` is created; it won’t work: Pour garantir la sécurité de la mémoire, il y a un autre petit détail qui se produit dans cette situation avec Rust. Plutôt qu'essayer de copier la mémoire -affectée, Rust considère que `s1` n'est plus en vigueur et du fait, Rust n'a pas +allouée, Rust considère que `s1` n'est plus en vigueur et donc, Rust n'a pas besoin de libérer quoi que ce soit lorsque `s1` sort de la portée. Regardez ce -qu'il se passe quand vous essayez d'utiliser `s1` après que `s2` soit créé, +qu'il se passe quand vous essayez d'utiliser `s1` après que `s2` est créé, cela ne va pas fonctionner : ```rust,ignore,does_not_compile @@ -804,13 +807,13 @@ shallow copy, it’s known as a *move*. In this example, we would say that `s1` was *moved* into `s2`. So what actually happens is shown in Figure 4-4. --> -Si vous avez déjà entendu parler de “copie superficielle” et de “copie en -profondeur” en utilisant d'autres langages, l'idée de copier le pointeur, la +Si vous avez déjà entendu parler de *copie superficielle* et de *copie +profonde* en utilisant d'autres langages, l'idée de copier le pointeur, la taille et la capacité sans copier les données peut vous faire penser à de la copie superficielle. Mais comme Rust neutralise aussi la première variable, au lieu d'appeler cela une copie superficielle, on appelle cela un *déplacement*. -Ici nous pourrions dire que `s1` a été *déplacé* dans `s2`. Donc voici ce qui se -passe réellement dans l'illustration 4-4. +Ici, nous pourrions dire que `s1` a été *déplacé* dans `s2`. Donc ce qui se +passe réellement est décrit par l'illustration 4-4. s1 moved to s2 @@ -819,8 +822,8 @@ passe réellement dans l'illustration 4-4. invalidated --> -Illustration 4-4 : représentation de la mémoire après que -`s1` ai été neutralisée +Illustration 4-4 : Représentation de la mémoire après que +`s1` a été neutralisée De plus, cela signifie qu'il y a eu un choix de conception : Rust ne va jamais -créer des copies “profondes” de vos données. Par conséquent, toute copie -*automatique* peut être considérée comme peu coûteuse en termes de performances -d'exécution. +créer automatiquement de copie “profonde” de vos données. Par conséquent, toute +copie *automatique* peut être considérée comme peu coûteuse en termes de +performances d'exécution. -Si nous *voulons* faire une copie profonde des données sur le tas d'un `String`, -et non pas seulement des données sur la pile, nous pouvons utiliser une méthode -commune qui s'appelle `clone`. Nous allons aborderons la syntaxe des méthodes -dans le chapitre 5, mais comme les méthodes sont des outils courants dans de -nombreux langages, vous les avez probablement utilisé auparavant. +Si nous *voulons* faire une copie profonde des données sur le tas d'une +`String`, et pas seulement des données sur la pile, nous pouvons utiliser une +méthode commune qui s'appelle `clone`. Nous aborderons la syntaxe des méthodes +au chapitre 5, mais comme les méthodes sont des outils courants dans de +nombreux langages, vous les avez probablement utilisées auparavant. -Quand vous voyez un appel à `clone`, vous savez que du code abstrait est exécuté -et que ce code peu coûteux. C'est un indicateur visuel qu'il se passe quelque -chose de différent. +Quand vous voyez un appel à `clone`, vous savez que du code arbitraire est +exécuté et que ce code peut être coûteux. C'est un indicateur visuel qu'il se +passe quelque chose de différent. -#### Données uniquement sur la pile : les copier +#### Données uniquement sur la pile : la copie -Il y a une autre faille dont on n'a pas encore parlé. Le code suivant utilise -des entiers, comme cela a déjà été montré dans l'encart 4-2, il fonctionne et +Il y a un autre détail dont on n'a pas encore parlé. Le code suivant utilise +des entiers, et on en a vu une partie dans l'encart 4-2 ; il fonctionne et est correct : ```rust @@ -919,7 +922,7 @@ But this code seems to contradict what we just learned: we don’t have a call t --> Mais ce code semble contredire ce que nous venons d'apprendre : nous n'avons -pas appelé un `clone`, mais `x` est toujours en vigueur et n'a pas été déplacé +pas appelé `clone`, mais `x` est toujours en vigueur et n'a pas été déplacé dans `y`. La raison est que les types comme les entiers ont une taille connue au moment de -la compilation et sont entièrement stockées sur la pile, donc la copie de la -valeur actuelle est rapide à faire. Cela signifie qu'il n'y a pas de raison que +la compilation et sont entièrement stockés sur la pile, donc la copie des +vraies valeurs est rapide à faire. Cela signifie qu'il n'y a pas de raison que nous voudrions neutraliser `x` après avoir créé la variable `y`. En d'autres termes, il n'y a pas ici de différence entre la copie superficielle et profonde, -donc appeler `clone` ne ferait rien de différent que la copie superficielle -classe et nous n'avons pas besoin de l'utiliser. +donc appeler `clone` ne ferait rien d'autre qu'une copie superficielle classique +et on peut s'en passer. sur les traits dérivables. -Donc, quels sont les types qui ont `Copy` ? Vous pouvez regarder dans la +Donc, quels sont les types qui sont `Copy` ? Vous pouvez regarder dans la documentation pour un type donné pour vous en assurer, mais de manière générale, tout groupe de valeur scalaire peut être `Copy`, et tout ce qui ne nécessite pas -d'affectation de mémoire ou tout autre forme quelconque de ressource est `Copy`. +d'allocation de mémoire ou tout autre forme de ressource est `Copy`. Voici quelques types qui sont `Copy` : -Encart 4-3 : les fonctions avec les possessions et les +Encart 4-3 : Les fonctions avec les possessions et les portées qui sont commentées -Si on essayait d'utiliser `s` après l'appel à `prendre_possession`, Rust va -déclencher une erreur au moment de la compilation. Ces vérifications statiques +Si on essayait d'utiliser `s` après l'appel à `prendre_possession`, Rust +déclencherait une erreur à la compilation. Ces vérifications statiques nous protègent des erreurs. Essayez d'ajouter du code au `main` qui utilise `s` et `x` pour découvrir lorsque vous pouvez les utiliser et lorsque les règles de la possession vous empêchent de le faire. @@ -1102,7 +1104,7 @@ Returning values can also transfer ownership. Listing 4-4 is an example with similar annotations to those in Listing 4-3. --> -Renvoyer les valeurs peut aussi transférer leur possession. L'encart 4-4 est un +Retourner des valeurs peut aussi transférer leur possession. L'encart 4-4 est un exemple avec des annotations similaires à celles de l'encart 4-3 : -Encart 4-4 : transferts de possessions des valeurs de +Encart 4-4 : Transferts de possession des valeurs de retour Il est un peu fastidieux de prendre la possession puis ensuite de retourner la -possession avec chaque fonction. Et qu'est ce qu'il se passe si nous voulons +possession à chaque fonction. Et qu'est-ce qu'il se passe si nous voulons qu'une fonction utilise une valeur, mais n'en prenne pas possession ? C'est -assez pénible que tout ce que nous envoyons doit être retourné si nous voulons -l'utiliser à nouveau, en plus de toutes les données qui découlent de l'exécution +assez pénible que tout ce que nous passons doit être retourné si nous voulons +l'utiliser à nouveau, en plus de toutes les données qui découlent du corps de la fonction que nous voulons aussi récupérer. -Encart 4-5 : retourner la possession des paramètres +Encart 4-5 : Retourner la possession des paramètres -Mais c'est trop cérémonieux et beaucoup de travail pour un principe qui devrait +Mais c'est trop laborieux et beaucoup de travail pour un principe qui devrait être banal. Heureusement pour nous, Rust a une fonctionnalité pour ce principe, c'est ce qu'on appelle les *références*. @@ -1282,4 +1284,7 @@ c'est ce qu'on appelle les *références*. [paths-module-tree]: ch07-03-paths-for-referring-to-an-item-in-the-module-tree.html --> -[data-types]: ch03-02-data-types.html#les-types-de-données +[data-types]: ch03-02-data-types.html +[derivable-traits]: appendix-03-derivable-traits.html +[method-syntax]: ch05-03-method-syntax.html +[paths-module-tree]: ch07-03-paths-for-referring-to-an-item-in-the-module-tree.html diff --git a/FRENCH/src/img/trpl04-01.svg b/FRENCH/src/img/trpl04-01.svg index 314f53ba12..c710fd89f9 100644 --- a/FRENCH/src/img/trpl04-01.svg +++ b/FRENCH/src/img/trpl04-01.svg @@ -15,18 +15,18 @@ s1 -name +nom -value +valeur -ptr +pointeur -len +taille 5 -capacity +capacité 5 @@ -34,9 +34,9 @@ table1 -index +indice -value +valeur 0 diff --git a/FRENCH/src/img/trpl04-02.svg b/FRENCH/src/img/trpl04-02.svg index 70d490f0bc..0ffc52c50e 100644 --- a/FRENCH/src/img/trpl04-02.svg +++ b/FRENCH/src/img/trpl04-02.svg @@ -15,18 +15,18 @@ s1 -name +nom -value +valeur -ptr +pointeur -len +taille 5 -capacity +capacité 5 @@ -34,9 +34,9 @@ table1 -index +indice -value +valeur 0 @@ -70,18 +70,18 @@ s2 -name +nom -value +valeur -ptr +pointeur -len +taille 5 -capacity +capacité 5 diff --git a/FRENCH/src/img/trpl04-03.svg b/FRENCH/src/img/trpl04-03.svg index 7c153e23a3..1d2d7327c8 100644 --- a/FRENCH/src/img/trpl04-03.svg +++ b/FRENCH/src/img/trpl04-03.svg @@ -15,18 +15,18 @@ s2 -name +nom -value +valeur -ptr +pointeur -len +taille 5 -capacity +capacité 5 @@ -34,9 +34,9 @@ table1 -index +indice -value +valeur 0 @@ -70,18 +70,18 @@ s1 -name +nom -value +valeur -ptr +pointeur -len +taille 5 -capacity +capacité 5 @@ -89,9 +89,9 @@ table4 -index +indice -value +valeur 0 diff --git a/FRENCH/src/img/trpl04-04.svg b/FRENCH/src/img/trpl04-04.svg index a0513abd90..a56ea03cc7 100644 --- a/FRENCH/src/img/trpl04-04.svg +++ b/FRENCH/src/img/trpl04-04.svg @@ -16,18 +16,18 @@ s1 -name +nom -value +valeur -ptr +pointeur -len +taille 5 -capacity +capacité 5 @@ -35,9 +35,9 @@ table1 -index +indice -value +valeur 0 @@ -71,18 +71,18 @@ s2 -name +nom -value +valeur -ptr +pointeur -len +taille 5 -capacity +capacité 5 From 23bfa8e230ef011bdc37122ed3b6bd4f33b31d22 Mon Sep 17 00:00:00 2001 From: Jimskapt Date: Fri, 25 Oct 2019 12:25:42 +0200 Subject: [PATCH 100/117] :ambulance: Proofreading ch05-01. --- FRENCH/src/ch05-01-defining-structs.md | 218 +++++++++++++------------ 1 file changed, 112 insertions(+), 106 deletions(-) diff --git a/FRENCH/src/ch05-01-defining-structs.md b/FRENCH/src/ch05-01-defining-structs.md index 004393e59e..7c40f29a9d 100644 --- a/FRENCH/src/ch05-01-defining-structs.md +++ b/FRENCH/src/ch05-01-defining-structs.md @@ -12,12 +12,12 @@ names, structs are more flexible than tuples: you don’t have to rely on the order of the data to specify or access the values of an instance. --> -Les structures sont similaires aux tuples, qu'on a abordés au chapitre 3. -Comme pour les tuples, les morceaux d'une structure peuvent être de types -différents. Contrairement aux tuples, on nomme chaque morceau de données pour -expliciter le rôle de chaque valeur. En conséquence de ces noms, les structures -sont plus flexibles que les tuples : on n'a pas à se fier à l'ordre des données -pour spécifier ou accéder aux valeurs d'une instance. +Les structures sont similaires aux tuples, qu'on a vu au chapitre 3. Comme pour +les tuples, les éléments d'une structure peuvent être de différents types. +Contrairement aux tuples, on doit nommer chaque élément des données afin de +clarifier le rôle de chaque valeur. Grâce à ces noms, les structures sont plus +flexibles que les tuples : on n'a pas à utiliser l'ordre des données pour +spécifier ou accéder aux valeurs d'une instance. -Pour définir une structure, on tape le mot-clé `struct` et on nomme la structure -tout entière. Le nom d'une structure devrait décrire l'importance des morceaux -de données regroupés. Puis, entre des accolades, on définit le nom et le type de -chaque morceau de données, qu'on appelle un *champ*. Par exemple, l'encart 5-1 -montre une structure qui stocke des informations à propos d'un compte -d'utilisateur. +Pour définir une structure, on tape le mot-clé `struct` et on donne un nom à +toute la structure. Le nom d'une structure devrait décrire l'utilisation des +éléments des données regroupées. Ensuite, entre des accolades, on définit le nom +et le type de chaque élément des données, qu'on appelle un *champ*. Par exemple, +l'encart 5-1 montre une structure qui stocke des informations à propos d'un +compte d'utilisateur. -Encart 5-1 : La définition d'une -structure `Utilisateur` +Encart 5-1 : La définition d'une structure +`Utilisateur` -Encart 5-2 : Création d'une instance de -la structure `Utilisateur` +Encart 5-2 : Création d'une instance de la structure +`Utilisateur` Pour obtenir une valeur spécifique depuis une structure, on utilise la notation -avec un point. Si nous voulions seulement l'adresse e-mail de cet utilisateur, +avec le point. Si nous voulions seulement l'adresse e-mail de cet utilisateur, on pourrait utiliser `utilisateur1.email` partout où on voudrait utiliser cette -valeur. Si l'instance est mutable, on peut changer une valeur en utilisant la -notation avec un point et en assignant une valeur à un champ en particulier. -L'encart 5-3 montre comment changer la valeur du champ `email` d'une instance -mutable de `Utilisateur`. +valeur. Si l'instance est mutable, nous pourrions changer une valeur en +utilisant la notation avec le point et assigner une valeur à ce champ en +particulier. L'encart 5-3 montre comment changer la valeur du champ `email` +d'une instance mutable de `Utilisateur`. -Encart 5-3 : Changement de la valeur du champ -`email` d'une instance de `Utilisateur` +Encart 5-3 : Changement de la valeur du champ `email` +d'une instance de `Utilisateur` -L'encart 5-4 montre une fonction `creer_utilisateur` qui renvoie une instance -de `Utilisateur` avec une adresse e-mail et un pseudo donnés. Le champ `actif` +L'encart 5-4 montre une fonction `creer_utilisateur` qui retourne une instance +de `Utilisateur` avec l'adresse e-mail et le pseudo fournis. Le champ `actif` prend la valeur `true` et le `nombre_de_connexions` prend la valeur `1`. Encart 5-4 : Une fonction `creer_utilisateur` qui prend -en entrée une adresse e-mail et un pseudo et retourne une instance -de `Utilisateur` +en entrée une adresse e-mail et un pseudo et retourne une instance de +`Utilisateur` -Puisque les noms de paramètres et les noms de champs de la structure sont +Puisque les noms des paramètres et les noms de champs de la structure sont exactement les mêmes dans l'encart 5-4, on peut utiliser la syntaxe de *raccourci d'initialisation des champs* pour réécrire `creer_utilisateur` de sorte qu'elle se comporte exactement de la même façon sans avoir à répéter -les mots `email` et `pseudo`, comme le montre l'encart 5-5. +`email` et `pseudo`, comme le montre l'encart 5-5. Il est souvent utile de créer une nouvelle instance de structure qui utilise la -plupart des valeurs d'une ancienne instance tout en en changeant certaines. -On utilisera la *syntaxe de mise à jour de structure* pour ce faire. +plupart des valeurs d'une ancienne instance tout en en changeant certaines. On +utilisera pour cela la *syntaxe de mise à jour de structure*. -Encart 5-6 : Création d'une nouvelle instance de `User` -en utilisant certaines valeurs de `user1`. +Encart 5-6 : Création d'une nouvelle instance de +`Utilisateur` en utilisant certaines valeurs de `utilisateur1`. En utilisant la syntaxe de mise à jour de structure, on peut produire le même -effet avec moins de code, comme le montre l'encart 5-7. La syntaxe `..` indique -que les champs restants auxquels on ne donne pas de valeur explicite devraient -avoir la même valeur que dans l'instance donnée. +résultat avec moins de code, comme le montre l'encart 5-7. La syntaxe `..` +indique que les autres champs auxquels on ne donne pas explicitement de valeur +devraient avoir la même valeur que dans l'instance précisée. Encart 5-7 : Utilisation de la syntaxe de mise à jour de -structure pour assigner de nouvelles valeurs à `email` et `pseudo` pour une -instance de `Utilisateur` tout en utilisant les autres valeurs des champs de -l'instance de la variable `utilisateur1` +structure pour assigner de nouvelles valeurs à `email` et `pseudo` à une +nouvelle instance de `Utilisateur` tout en utilisant les autres valeurs des +champs de l'instance de la variable `utilisateur1` La définition d'une structure tuple commence par le mot-clé `struct` et le nom -de la structure suivis des types des champs du tuple. Par exemple, voici -comment définir et utiliser deux structures tuples nommées `Couleur` et +de la structure suivis des types des champs du tuple. Par exemple, voici une +définition et une utilisation de deux structures tuples nommées `Couleur` et `Point` : -À noter que les valeurs `noir` et `origine` sont de types différents parce que -ce sont des instances de structures tuples différentes. Chaque structure que -l'on définit constitue son propre type, même si les champs au sein de la -structure ont les mêmes types. Par exemple, une fonction qui prend un paramètre -de type `Couleur` ne peut pas prendre un argument de type `Point` à la place, -bien que les deux types soient constitués de trois valeurs `i32`. En dehors de -ça, les instances de stuctures tuples se comportent comme des tuples : on peut -les déstructurer en morceaux individuels, on peut utiliser un `.` suivi de -l'indice pour accéder à une valeur individuelle, et ainsi de suite. +Notez que les valeurs `noir` et `origine` sont de types différents parce que ce +sont des instances de structures tuples différentes. Chaque structure que l'on +définit constitue son propre type, même si les champs au sein de la structure +ont les mêmes types. Par exemple, une fonction qui prend un paramètre de type +`Couleur` ne peut pas prendre un argument de type `Point` à la place, bien que +ces deux types soient tous les deux constitués de trois valeurs `i32`. Mis à +part cela, les instances de stuctures tuples se comportent comme des tuples : on +peut les déstructurer en éléments individuels, en utilisant un `.` suivi de +l'indice pour accéder individuellement à une valeur, et ainsi de suite. -On peut aussi définir des structures qui n'ont pas de champs ! On les appelle -des *structures unitaires* parce qu'elles se comportent d'une façon analogue -au type unité `()`. Les structures unitaires peuvent être utiles quand on doit -implémenter un trait sur un type mais qu'on n'a pas de données à stocker dans -le type lui-même. Nous aborderons les traits au chapitre 10. +On peut aussi définir des structures qui n'ont pas de champs ! Cela s'appelle +des *structures unitaires* parce qu'elles se comportent d'une façon analogue au +type unitaire, `()`. Les structures unitaires sont utiles lorsqu'on doit +implémenter un trait sur un type mais qu'on n'a aucune donnée à stocker dans +le type en lui-même. Nous aborderons les traits au chapitre 10. -> -> ### Possession des données d'une structure + -> -> Dans la définition de la structure `Utilisateur` dans l'encart 5-1, nous -> avions utilisé le type possédé `String` plutôt que le type de *slice* de -> chaîne de caractères `&str`. Il s'agit d'un choix délibéré puisque nous -> voulons que les instances de cette structure possèdent toutes leurs données et -> que ces données soient valides tant que la structure tout entière est valide. > -> -> -> Il est possible pour les structures de stocker des références à des données -> possédées par autre chose, mais cela nécessiterait d'utiliser des -> *durées de vie*, une fonctionnalité de Rust que nous aborderons au -> chapitre 10. Les durées de vie s'assurent que les données référencées par une -> structure sont valides aussi longtemps que la structure est valide aussi. -> Disons que vous essayiez de stocker une référence dans une structure sans -> indiquer de durées de vie, comme ceci, ce qui ne fonctionnera pas : > -> > -> Fichier : src/main.rs -> -> +> +> +> The compiler will complain that it needs lifetime specifiers: +> +> ```text +> error[E0106]: missing lifetime specifier +> -- > +> | +> 2 | username: &str, +> | ^ expected lifetime parameter +> +> error[E0106]: missing lifetime specifier +> -- > +> | +> 3 | email: &str, +> | ^ expected lifetime parameter +> ``` +> +> In Chapter 10, we’ll discuss how to fix these errors so you can store +> references in structs, but for now, we’ll fix errors like these using owned +> types like `String` instead of references like `&str`. +--> + +> ### La possession des données d'une structure +> +> Dans la définition de la structure `Utilisateur` de l'encart 5-1, nous avions +> utilisé le type possédé `String` plutôt que le type de *slice* de chaîne de +> caractères `&str`. Il s'agit d'un choix délibéré puisque nous voulons que les +> instances de cette structure possèdent toutes leurs données et que ces données +> restent valides tant que la structure tout entière est valide. +> +> Il est possible pour les structures de stocker des références vers des données +> possédées par autre chose, mais cela nécessiterait d'utiliser des +> *durées de vie*, une fonctionnalité de Rust que nous aborderons au +> chapitre 10. Les durées de vie assurent que les données référencées par une +> structure restent valides tant que la structure l'est aussi. Disons que vous +> essayiez de stocker une référence dans une structure sans indiquer de durées +> de vie, comme ceci, ce qui ne fonctionnera pas : +> +> Fichier : src/main.rs > > ```rust,ignore,does_not_compile > struct Utilisateur { @@ -681,11 +697,7 @@ le type lui-même. Nous aborderons les traits au chapitre 10. > } > ``` > -> -> -> Le compilateur se plaindra qu'il a besoin de spécificateurs de durées de vie : +> Le compilateur réclamera l'ajout des durées de vie : > > ```text > error[E0106]: missing lifetime specifier @@ -701,13 +713,7 @@ le type lui-même. Nous aborderons les traits au chapitre 10. > | ^ expected lifetime parameter > ``` > -> -> > Au chapitre 10, nous aborderons la façon de corriger ces erreurs pour qu'on > puisse stocker des références dans des structures, mais pour le moment, nous -> corrigerons les erreurs comme celles-ci en utilisant des types possédés comme +> résoudrons les erreurs comme celles-ci en utilisant des types possédés comme > `String` plutôt que des références comme `&str`. From 58c99f1c668b0ec55e85bf41d73a45a5296a1e54 Mon Sep 17 00:00:00 2001 From: Thomas Ramirez Date: Sat, 26 Oct 2019 01:14:17 +0200 Subject: [PATCH 101/117] Updating translating terms due to proofreading 729404a See 729404a. --- FRENCH/src/translation-terms.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/FRENCH/src/translation-terms.md b/FRENCH/src/translation-terms.md index 9e5d53175d..5d29bb2092 100644 --- a/FRENCH/src/translation-terms.md +++ b/FRENCH/src/translation-terms.md @@ -126,11 +126,11 @@ français. | pattern-matching | filtrage par motif | - | | placeholder | espace réservé | `{}` pour `fmt` | | pointer | pointeur | - | -| popping off the stack | retirer de la pile | - | +| popping off the stack | dépiler | - | | prelude | étape préliminaire | - | | procedural macro | macro procédurale | - | | project chapter | chapitre de projet | - | -| pushing onto the stack | déposer sur la pile | - | +| pushing onto the stack | empiler | - | | raw identifier | identificateur brut | - | | README | README | - | | refactoring | remaniement | - | @@ -172,7 +172,7 @@ français. | statement | instruction | - | | statically typed | statiquement typé | - | | string | chaîne de caractères | - | -| string literal | chaîne de caractères pure | - | +| string literal | un littéral de chaîne de caractères | - | | `String` | `String` | nom féminin (une `String`) | | struct | structure | - | | submodule | sous-module | - | From 5abc8538e11118ae2b9e2e1c043eedd1a4a1c6d8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=ABl=20J=2E=20Pr=C3=A9sent?= <36854931+joeljpresent@users.noreply.github.com> Date: Sat, 26 Oct 2019 10:18:41 +0200 Subject: [PATCH 102/117] Proof-proofread ch05-01 --- FRENCH/src/ch05-01-defining-structs.md | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/FRENCH/src/ch05-01-defining-structs.md b/FRENCH/src/ch05-01-defining-structs.md index 7c40f29a9d..d4d77b73eb 100644 --- a/FRENCH/src/ch05-01-defining-structs.md +++ b/FRENCH/src/ch05-01-defining-structs.md @@ -12,7 +12,7 @@ names, structs are more flexible than tuples: you don’t have to rely on the order of the data to specify or access the values of an instance. --> -Les structures sont similaires aux tuples, qu'on a vu au chapitre 3. Comme pour +Les structures sont similaires aux tuples, qu'on a vus au chapitre 3. Comme pour les tuples, les éléments d'une structure peuvent être de différents types. Contrairement aux tuples, on doit nommer chaque élément des données afin de clarifier le rôle de chaque valeur. Grâce à ces noms, les structures sont plus @@ -29,7 +29,7 @@ struct that stores information about a user account. Pour définir une structure, on tape le mot-clé `struct` et on donne un nom à toute la structure. Le nom d'une structure devrait décrire l'utilisation des -éléments des données regroupées. Ensuite, entre des accolades, on définit le nom +éléments des données regroupés. Ensuite, entre des accolades, on définit le nom et le type de chaque élément des données, qu'on appelle un *champ*. Par exemple, l'encart 5-1 montre une structure qui stocke des informations à propos d'un compte d'utilisateur. @@ -75,7 +75,7 @@ example, we can declare a particular user as shown in Listing 5-2. Pour utiliser une structure après l'avoir définie, on crée une *instance* de cette structure en indiquant des valeurs concrètes pour chacun des champs. -On crée une instance en évoquant le nom de la structure puis en ajoutant des +On crée une instance en indiquant le nom de la structure puis en ajoutant des accolades qui contiennent des paires de `clé: valeur`, où les clés sont les noms des champs et les valeurs sont les données que l'on souhaite stocker dans ces champs. Nous n'avons pas à préciser les champs dans le même ordre qu'on les a @@ -582,14 +582,14 @@ ont les mêmes types. Par exemple, une fonction qui prend un paramètre de type `Couleur` ne peut pas prendre un argument de type `Point` à la place, bien que ces deux types soient tous les deux constitués de trois valeurs `i32`. Mis à part cela, les instances de stuctures tuples se comportent comme des tuples : on -peut les déstructurer en éléments individuels, en utilisant un `.` suivi de +peut les déstructurer en éléments individuels, on peut utiliser un `.` suivi de l'indice pour accéder individuellement à une valeur, et ainsi de suite. -### Les structures unitaires sans champs +### Les structures unité sans champs On peut aussi définir des structures qui n'ont pas de champs ! Cela s'appelle -des *structures unitaires* parce qu'elles se comportent d'une façon analogue au -type unitaire, `()`. Les structures unitaires sont utiles lorsqu'on doit -implémenter un trait sur un type mais qu'on n'a aucune donnée à stocker dans -le type en lui-même. Nous aborderons les traits au chapitre 10. +des *structures unité* parce qu'elles se comportent d'une façon analogue au type +unité, `()`. Les structures unité sont utiles lorsqu'on doit implémenter un +trait sur un type mais qu'on n'a aucune donnée à stocker dans le type en +lui-même. Nous aborderons les traits au chapitre 10. + +## Un programme d'exemple qui utilise des structures + + + +Pour comprendre dans quels cas on voudrait utiliser des structures, écrivons un +programme qui calcule l'aire d'un rectangle. Nous commencerons avec de simples +variables, puis on remaniera le code jusqu'à utiliser des structures à la place. + + + +Créons un nouveau projet binaire avec Cargo nommé *rectangles* qui prendra la +largeur et la hauteur en pixels d'un rectangle et qui calculera l'aire de ce +rectangle. L'encart 5-8 montre un court programme qui effectue cette tâche d'une +certaine manière dans le *src/main.rs* de notre projet. + + + +Nom de fichier : src/main.rs + + + +```rust +fn main() { + let largeur1 = 30; + let hauteur1 = 50; + + println!( + "L'aire du rectangle est de {} pixels carrés.", + aire(largeur1, hauteur1) + ); +} + +fn aire(largeur: u32, hauteur: u32) -> u32 { + largeur * hauteur +} +``` + + + +Encart 5-8 : Calcul de l'aire d'un rectangle défini par +des variables séparées de largeur et de hauteur + + + +Maintenant, lancez ce programme avec `cargo run` : + + + +```text +L'aire du rectangle est de 1500 pixels carrés. +``` + + + +Bien que l'encart 5-8 fonctionne et détermine l'aire du rectangle en appelant +la fonction `aire` avec chaque dimension, on peut faire mieux. La largeur et la +hauteur sont liées entre elles car elles décrivent un rectangle à elles deux. + + + +Le problème de ce code transparaît dans la signature de `aire` : + + + +```rust,ignore +fn aire(largeur: u32, hauteur: u32) -> u32 { +``` + + + +La fonction `aire` est censée calculer l'aire d'un rectangle, mais la fonction +que nous avons écrite a deux paramètres. Les paramètres sont liés, mais ce n'est +exprimé nulle part dans notre programme. Il serait plus lisible et plus gérable +de regrouper la largeur et la hauteur. Nous avons déjà vu une façon de le +faire dans la section [“Le type *tuple*”][the-tuple-type] du +chapitre 3 : en utilisant des tuples. + + + +### Remanier le code avec des tuples + + + +L'encart 5-9 nous montre une autre version de notre programme qui utilise des +tuples. + + + +Fichier : src/main.rs + + + +```rust +fn main() { + let rect1 = (30, 50); + + println!( + "L'aire du rectangle est de {} pixels carrés.", + aire(rect1) + ); +} + +fn aire(dimensions: (u32, u32)) -> u32 { + dimensions.0 * dimensions.1 +} +``` + + + +Encart 5-9 : Spécifier la largeur et la hauteur du +rectangle avec un tuple + + + +D'une certaine façon, ce programme est mieux. Les tuples nous permettent de +structurer un peu plus et nous ne passons plus qu'un argument. Mais d'une autre +façon, cette version est moins claire : les tuples ne donnent pas de noms à +leurs éléments, donc notre calcul est devenu plus déroutant puisqu'il faut +accéder aux éléments du tuple via leur indice. + + + +Ce n'est pas grave de confondre la largeur et la hauteur pour calculer l'aire, +mais si on voulait afficher le rectangle à l'écran, cela serait problématique ! +Il faudrait garder à l'esprit que la `largeur` est l'élément d'indice 0 du tuple +et que la `hauteur` est l'élément d'indice 1. Si quelqu'un d'autre travaillait +sur ce code, il devrait le deviner et s'en souvenir aussi. Il serait facile +d'oublier ou de confondre ces valeurs et ainsi de provoquer des erreurs, parce +qu'on n'a pas exprimé la signification de nos données dans le code. + + + +### Remanier avec des structures : donner du sens + + + +On utilise des structures pour rendre les données significatives en leur donnant +des noms. On peut transformer notre tuple en type de donnée nommé dont les +parties sont nommées elles aussi, comme le montre l'encart 5-10. + + + +Fichier : src/main.rs + + + +```rust +struct Rectangle { + largeur: u32, + hauteur: u32, +} + +fn main() { + let rect1 = Rectangle { largeur: 30, hauteur: 50 }; + + println!( + "L'aire du rectangle est de {} pixels carrés.", + aire(&rect1) + ); +} + +fn aire(rectangle: &Rectangle) -> u32 { + rectangle.largeur * rectangle.hauteur +} +``` + + + +Encart 5-10 : Définition d'une structure +`Rectangle` + + + +Ici, on a défini une structure et on l'a appelée `Rectangle`. Entre les +accolades, on a défini les champs `largeur` et `hauteur`, tous deux du type +`u32`. Puis dans `main`, on crée une instance particulière de `Rectangle` de +largeur 30 et de hauteur 50. + + + +Notre fonction `aire` est désormais définie avec un unique paramètre, nommé +`rectangle`, et dont le type est une référence immuable vers une instance de la +structure `Rectangle`. Comme mentionné au chapitre 4, on veut emprunter la +structure au lieu d'en prendre possession. Ainsi, elle reste en possession de +`main` qui peut continuer à utiliser `rect1` ; c'est pourquoi on utilise le `&` +dans la signature de la fonction ainsi que dans l'appel de fonction. + + + +La fonction `aire` accède aux champs `largeur` et `hauteur` de l'instance de +`Rectangle`. Notre signature de fonction pour `aire` est enfin explicite : +calculer l'aire d'un `Rectangle` en utilisant ses champs `largeur` et `hauteur`. +Cela reflète que la largeur et la hauteur sont liées entre elles, et cela donne +des noms descriptifs aux valeurs plutôt que d'utiliser les valeurs d'indices `0` +et `1`. On gagne en clarté. + + + +### Ajouter des fonctionnalités utiles avec les traits dérivés + + + +Il serait bien de pouvoir afficher une instance de `Rectangle` pendant qu'on +débogue notre programme et de voir la valeur de chacun de ses champs. L'encart +5-11 essaie de le faire en utilisant la macro `println!` comme on l'a fait +dans les chapitres précédents. Cependant, cela ne fonctionnera pas. + + + +Fichier : src/main.rs + + + +```rust,ignore,does_not_compile +struct Rectangle { + largeur: u32, + hauteur: u32, +} + +fn main() { + let rect1 = Rectangle { largeur: 30, hauteur: 50 }; + + println!("rect1 est {}", rect1); +} +``` + + + +Encart 5-11 : Tentative d'afficher une instance de +`Rectangle` + + + +Quand on exécute ce code, on obtient ce message d'erreur qui nous informe que +`Rectangle` n'implémente pas le trait `std::fmt::Display` : + +```text +error[E0277]: `Rectangle` doesn't implement `std::fmt::Display` +``` + + + +La macro `println!` peut faire toutes sortes de formatages de texte, et par +défaut, les accolades demandent à `println!` d'utiliser le formatage appelé +`Display`, pour du texte destiné à être vu par l'utilisateur final. Les types +primitifs qu'on a vus jusqu'ici implémentent `Display` par défaut puisqu'il +n'existe qu'une seule façon d'afficher un `1` ou tout autre type primitif à +l'utilisateur. Mais pour les structures, la façon dont `println!` devrait +formater la sortie est moins claire car il y a plus de possibilités +d'affichage : Voulez-vous des virgules ? Voulez-vous afficher les accolades ? +Tous les champs devraient-ils être affichés ? À cause de cette ambigüité, Rust +n'essaie pas de deviner ce qu'on veut, et les structures n'implémentent pas +`Display` par défaut. + + + +Si nous continuons de lire les erreurs, nous trouvons cette remarque utile : + +```text += help: the trait `std::fmt::Display` is not implemented for `Rectangle` += note: in format strings you may be able to use `{:?}` (or {:#?} for pretty-print) instead +``` + +Le compilateur nous informe que dans notre chaîne de formatage, on est peut-être +en mesure d'utiliser `{:?}` (ou `{:#?}` pour l'affichage élégant). + + + +Essayons ! L'appel de la macro `println!` ressemble maintenant à +`println!("rect1 est {:?}", rect1);`. Mettre le spécificateur `:?` entre les +accolades permet d'informer `println!` que nous voulons utiliser le formatage +appelé `Debug`. Le trait `Debug` nous permet d'afficher notre structure d'une +façon utile aux dévelopeurs pour qu'on puisse voir sa valeur pendant qu'on +débogue le code. + + + +Exécutez le code avec ce changement. Zut ! On a encore une erreur, nous +informant cette fois-ci que `Rectangle` n'implémente pas `std::fmt::Debug` : + +```text +error[E0277]: `Rectangle` doesn't implement `std::fmt::Debug` +``` + + + +Mais une nouvelle fois, le compilateur nous fait une remarque utile : + +```text += help: the trait `std::fmt::Debug` is not implemented for `Rectangle` += note: add `#[derive(Debug)]` or manually implement `std::fmt::Debug` +``` + +Il nous conseille d'ajouter `#[derive(Debug)]` ou d'implémenter manuellement +`std::fmt::Debug`. + + + +Rust inclut bel et bien une fonctionnalité pour afficher des informations de +débogage, mais nous devons l'activer explicitement pour la rendre disponible +à notre structure. Pour ce faire, on ajoute l'annotation `#[derive(Debug)]` +juste avant la définition de la structure, comme le montre l'encart 5-12. + + + +Fichier : src/main.rs + + + +```rust +#[derive(Debug)] +struct Rectangle { + largeur: u32, + hauteur: u32, +} + +fn main() { + let rect1 = Rectangle { largeur: 30, hauteur: 50 }; + + println!("rect1 est {:?}", rect1); +} +``` + + + +Encart 5-12 : L'ajout de l'annotation pour dériver le +trait `Debug` et afficher l'instance de `Rectangle` en utilisant le formatage +de débogage + + + +Maintenant, quand on exécute le programme, nous n'avons plus d'erreur et ce +texte s'affiche à l'écran : + + + +```text +rect1 est Rectangle { largeur: 30, hauteur: 50 } +``` + + + +Chouette ! C'est n'est pas le plus beau des affichages, mais cela montre les +valeurs de tous les champs de cette instance, ce qui serait assurément utile +lors du débogage. Quand on a des structures plus grandes, il serait bien d'avoir +un affichage un peu plus lisible ; dans ces cas-là, on pourra utiliser `{:#?}` +au lieu de `{:?}` dans la chaîne de formatage. Quand on utilise `{:#?}` dans cet +exemple, l'affichage sera plutôt comme ceci : + + + +```text +rect1 est Rectangle { + largeur: 30, + hauteur: 50, +} +``` + + + +Rust nous fournit un certain nombre de traits qu'on peut utiliser avec +l'annotation `derive` qui peuvent ajouter des comportements utiles à nos propres +types. Ces traits et leurs comportements sont listés à l'annexe C. Nous +expliquerons comment implémenter ces traits avec des comportements personnalisés +et comment créer vos propres traits au chapitre 10. + + + +Notre fonction `aire` est très spécifique : elle ne fait que calculer l'aire +d'un rectangle. Il serait utile de lier un peu plus ce comportement à notre +structure `Rectangle`, puisque cela ne fonctionnera pas avec tout autre type. +Voyons comment on peut continuer de remanier ce code en transformant la fonction +`aire` en *méthode* `aire` définie sur notre type `Rectangle`. + + + +[the-tuple-type]: ch03-02-data-types.html#le-type-tuple From 2a6d11b852b93355794a8ff22b24c07e8da1f744 Mon Sep 17 00:00:00 2001 From: Jimskapt Date: Mon, 28 Oct 2019 13:13:47 +0100 Subject: [PATCH 105/117] :ambulance: Proofreading ch05-02. --- FRENCH/src/SUMMARY.md | 2 +- FRENCH/src/ch05-02-example-structs.md | 118 ++++++++++++++------------ 2 files changed, 63 insertions(+), 57 deletions(-) diff --git a/FRENCH/src/SUMMARY.md b/FRENCH/src/SUMMARY.md index 3abe3b333e..64539c7391 100644 --- a/FRENCH/src/SUMMARY.md +++ b/FRENCH/src/SUMMARY.md @@ -26,4 +26,4 @@ - [Utiliser les structures pour structurer des données apparentées](ch05-00-structs.md) - [Définir et instancier des structures](ch05-01-defining-structs.md) - - [Un programme d'exemple qui utilise des structures](ch05-02-example-structs.md) + - [Un exemple de programme qui utilise des structures](ch05-02-example-structs.md) diff --git a/FRENCH/src/ch05-02-example-structs.md b/FRENCH/src/ch05-02-example-structs.md index 6fda214fc0..918e2098fd 100644 --- a/FRENCH/src/ch05-02-example-structs.md +++ b/FRENCH/src/ch05-02-example-structs.md @@ -1,8 +1,10 @@ + + -## Un programme d'exemple qui utilise des structures +## Un exemple de programme qui utilise des structures -Pour comprendre dans quels cas on voudrait utiliser des structures, écrivons un -programme qui calcule l'aire d'un rectangle. Nous commencerons avec de simples -variables, puis on remaniera le code jusqu'à utiliser des structures à la place. +Pour comprendre dans quels cas nous voudrions utiliser des structures, écrivons +un programme qui calcule l'aire d'un rectangle. Nous commencerons avec de +simples variables, puis on remaniera le code jusqu'à utiliser des structures à +la place. -Nom de fichier : src/main.rs +Fichier: src/main.rs Encart 5-8 : Calcul de l'aire d'un rectangle défini par -des variables séparées de largeur et de hauteur +les variables distinctes largeur et hauteur -Le problème de ce code transparaît dans la signature de `aire` : +Le problème de ce code se voit dans la signature de `aire` : La fonction `aire` est censée calculer l'aire d'un rectangle, mais la fonction que nous avons écrite a deux paramètres. Les paramètres sont liés, mais ce n'est exprimé nulle part dans notre programme. Il serait plus lisible et plus gérable -de regrouper la largeur et la hauteur. Nous avons déjà vu une façon de le -faire dans la section [“Le type *tuple*”][the-tuple-type] du -chapitre 3 : en utilisant des tuples. +de regrouper ensemble la largeur et la hauteur. Nous avons déjà vu dans la +section [“Le type *tuple*”][the-tuple-type] du chapitre 3 une +façon qui nous permettrait de le faire : en utilisant des tuples. -Encart 5-9 : Spécifier la largeur et la hauteur du -rectangle avec un tuple +Encart 5-9 : Renseigner la largeur et la hauteur du +rectangle dans un tuple -D'une certaine façon, ce programme est mieux. Les tuples nous permettent de +D'une certaine façon, ce programme est meilleur. Les tuples nous permettent de structurer un peu plus et nous ne passons plus qu'un argument. Mais d'une autre façon, cette version est moins claire : les tuples ne donnent pas de noms à leurs éléments, donc notre calcul est devenu plus déroutant puisqu'il faut @@ -217,17 +221,18 @@ our code. Ce n'est pas grave de confondre la largeur et la hauteur pour calculer l'aire, mais si on voulait afficher le rectangle à l'écran, cela serait problématique ! -Il faudrait garder à l'esprit que la `largeur` est l'élément d'indice 0 du tuple -et que la `hauteur` est l'élément d'indice 1. Si quelqu'un d'autre travaillait -sur ce code, il devrait le deviner et s'en souvenir aussi. Il serait facile -d'oublier ou de confondre ces valeurs et ainsi de provoquer des erreurs, parce -qu'on n'a pas exprimé la signification de nos données dans le code. +Il nous faut garder à l'esprit que la `largeur` est l'élément à l'indice 0 du +tuple et que la `hauteur` est l'élément à l'indice 1. Si quelqu'un d'autre +travaillait sur ce code, il devrait le déduire et s'en souvenir aussi. Il est +facile d'oublier ou de confondre ces valeurs et par conséquent provoquer des +erreurs, parce qu'on n'a pas exprimé la signification de nos données dans notre +code. -### Remanier avec des structures : donner du sens +### Remanier avec des structures : donner plus de sens -On utilise des structures pour rendre les données significatives en leur donnant -des noms. On peut transformer notre tuple en type de donnée nommé dont les -parties sont nommées elles aussi, comme le montre l'encart 5-10. +On utilise des structures pour rendre les données plus expressives en leur +donnant des noms. On peut transformer le tuple que nous avons utilisé en un type +de donnée nommé dont ses éléments sont aussi nommés, comme le montre l'encart +5-10. -Il serait bien de pouvoir afficher une instance de `Rectangle` pendant qu'on +Cela serait bien de pouvoir afficher une instance de `Rectangle` pendant qu'on débogue notre programme et de voir la valeur de chacun de ses champs. L'encart -5-11 essaie de le faire en utilisant la macro `println!` comme on l'a fait -dans les chapitres précédents. Cependant, cela ne fonctionnera pas. +5-11 essaye de le faire en utilisant la macro `println!` comme on l'a fait +dans les chapitres précédents. Cependant, cela ne fonctionne pas. -Quand on exécute ce code, on obtient ce message d'erreur qui nous informe que +Lorsqu'on exécute ce code, on obtient ce message d'erreur qui nous informe que `Rectangle` n'implémente pas le trait `std::fmt::Display` : ```text @@ -422,16 +428,16 @@ doesn’t try to guess what we want, and structs don’t have a provided implementation of `Display`. --> -La macro `println!` peut faire toutes sortes de formatages de texte, et par +La macro `println!` peut faire toutes sortes de formatages textuels, et par défaut, les accolades demandent à `println!` d'utiliser le formatage appelé -`Display`, pour du texte destiné à être vu par l'utilisateur final. Les types -primitifs qu'on a vus jusqu'ici implémentent `Display` par défaut puisqu'il -n'existe qu'une seule façon d'afficher un `1` ou tout autre type primitif à -l'utilisateur. Mais pour les structures, la façon dont `println!` devrait -formater la sortie est moins claire car il y a plus de possibilités +`Display`, pour convertir en texte destiné à être vu par l'utilisateur final. +Les types primaires qu'on a vus jusqu'ici implémentent `Display` par défaut +puisqu'il n'existe qu'une seule façon d'afficher un `1` ou tout autre type +primaire à l'utilisateur. Mais pour les structures, la façon dont `println!` +devrait formater son résultat est moins claire car il y a plus de possibilités d'affichage : Voulez-vous des virgules ? Voulez-vous afficher les accolades ? -Tous les champs devraient-ils être affichés ? À cause de cette ambigüité, Rust -n'essaie pas de deviner ce qu'on veut, et les structures n'implémentent pas +Est-ce que tous les champs devraient être affichés ? À cause de ces ambigüités, +Rust n'essaye pas de deviner ce qu'on veut, et les structures n'implémentent pas `Display` par défaut. -Essayons ! L'appel de la macro `println!` ressemble maintenant à -`println!("rect1 est {:?}", rect1);`. Mettre le spécificateur `:?` entre les -accolades permet d'informer `println!` que nous voulons utiliser le formatage +Essayons cela ! L'appel de la macro `println!` ressemble maintenant à +`println!("rect1 est {:?}", rect1);`. Insérer le sélecteur `:?` entre les +accolades permet d'indiquer à `println!` que nous voulons utiliser le formatage appelé `Debug`. Le trait `Debug` nous permet d'afficher notre structure d'une -façon utile aux dévelopeurs pour qu'on puisse voir sa valeur pendant qu'on +manière utile aux développeurs pour qu'on puisse voir sa valeur pendant qu'on débogue le code. -Rust inclut bel et bien une fonctionnalité pour afficher des informations de -débogage, mais nous devons l'activer explicitement pour la rendre disponible -à notre structure. Pour ce faire, on ajoute l'annotation `#[derive(Debug)]` -juste avant la définition de la structure, comme le montre l'encart 5-12. +Rust *inclut* bel et bien une fonctionnalité pour afficher des informations de +débogage, mais nous devons l'activer explicitement pour la rendre disponible sur +notre structure. Pour ce faire, on ajoute l'annotation `#[derive(Debug)]` juste +avant la définition de la structure, comme le montre l'encart 5-12. -Chouette ! C'est n'est pas le plus beau des affichages, mais cela montre les +Super ! C'est n'est pas le plus beau des affichages, mais cela montre les valeurs de tous les champs de cette instance, ce qui serait assurément utile lors du débogage. Quand on a des structures plus grandes, il serait bien d'avoir un affichage un peu plus lisible ; dans ces cas-là, on pourra utiliser `{:#?}` au lieu de `{:?}` dans la chaîne de formatage. Quand on utilise `{:#?}` dans cet -exemple, l'affichage sera plutôt comme ceci : +exemple, l'affichage donnera plutôt ceci : - @@ -434,9 +432,9 @@ défaut, les accolades demandent à `println!` d'utiliser le formatage appelé Les types primaires qu'on a vus jusqu'ici implémentent `Display` par défaut puisqu'il n'existe qu'une seule façon d'afficher un `1` ou tout autre type primaire à l'utilisateur. Mais pour les structures, la façon dont `println!` -devrait formater son résultat est moins claire car il y a plus de possibilités +devrait formater son résultat est moins clair car il y a plus de possibilités d'affichage : Voulez-vous des virgules ? Voulez-vous afficher les accolades ? -Est-ce que tous les champs devraient être affichés ? À cause de ces ambigüités, +Est-ce que tous les champs devraient être affichés ? À cause de ces ambiguïtés, Rust n'essaye pas de deviner ce qu'on veut, et les structures n'implémentent pas `Display` par défaut. @@ -556,7 +554,7 @@ Now when we run the program, we won’t get any errors, and we’ll see the following output: --> -Maintenant, quand on exécute le programme, nous n'avons plus d'erreur et ce +Maintenant, quand on exécute le programme, nous n'avons plus d'erreurs et ce texte s'affiche à l'écran : -Super ! C'est n'est pas le plus beau des affichages, mais cela montre les +Super ! Ce n'est pas le plus beau des affichages, mais cela montre les valeurs de tous les champs de cette instance, ce qui serait assurément utile lors du débogage. Quand on a des structures plus grandes, il serait bien d'avoir un affichage un peu plus lisible ; dans ces cas-là, on pourra utiliser `{:#?}` From 8719489c6d58a78c8612750e0082aac2102e8d46 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=ABl=20J=2E=20Pr=C3=A9sent?= <36854931+joeljpresent@users.noreply.github.com> Date: Thu, 31 Oct 2019 10:51:22 +0100 Subject: [PATCH 107/117] Proof-proofread ch05-02 --- FRENCH/src/ch05-02-example-structs.md | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/FRENCH/src/ch05-02-example-structs.md b/FRENCH/src/ch05-02-example-structs.md index c5b0cd67b2..d7d57c49b3 100644 --- a/FRENCH/src/ch05-02-example-structs.md +++ b/FRENCH/src/ch05-02-example-structs.md @@ -73,7 +73,7 @@ specified by separate width and height variables --> Encart 5-8 : Calcul de l'aire d'un rectangle défini par -les variables distinctes largeur et hauteur +les variables distinctes `largeur` et `hauteur` -L'installateur embarque aussi une copie de la documentation en local pour que -vous puissiez la lire hors ligne. Lancez `rustup doc` afin -d'ouvrir la documentation locale dans votre navigateur. +L'installation de Rust embarque aussi une copie de la documentation en local +pour que vous puissiez la lire hors ligne. Lancez `rustup doc` afin d'ouvrir la +documentation locale dans votre navigateur. Ouvrez un terminal et écrivez les commandes suivantes pour créer un -dossier *projects* et un dossier pour le projet *Hello, world!* à l'intérieur +dossier *projects* et un dossier pour le projet “Hello, world!” à l'intérieur de ce dossier *projects*. -Regardons en détail ce qui s'est passé dans votre programme *Hello, world!*. +Regardons en détail ce qui s'est passé dans votre programme “Hello, world!”. Voici le premier morceau du puzzle : ```rust @@ -394,11 +394,11 @@ $ ./main # ou .\main.exe sous Windows ``` -Si *main.rs* était votre programme *Hello, world!*, cette ligne devrait afficher +Si *main.rs* était votre programme “Hello, world!”, cette ligne devrait afficher `Hello, world!` dans votre terminal. Des programmes Rust très simples, comme le petit que nous avons précédemment, -n'ont pas de dépendance. Donc si nous avions compilé le projet *Hello, world!* +n'ont pas de dépendance. Donc si nous avions compilé le projet “Hello, world!” avec Cargo, cela n'aurait fait appel qu'à la fonctionnalité de Cargo qui s'occupe de la compilation de votre code. Quand vous écrirez des programmes Rust plus complexes, vous ajouterez des dépendances, et si vous créez un projet en @@ -71,13 +71,13 @@ séparément Cargo. Créons un nouveau projet en utilisant Cargo et analysons les différences avec -notre projet initial *Hello, world!*. Retournez dans votre dossier *projects* +notre projet initial “Hello, world!”. Retournez dans votre dossier *projects* (ou là où vous avez décidé d'enregistrer votre code). Ensuite, sur n'importe quel système d'exploitation, lancez les commandes suivantes : @@ -220,13 +220,13 @@ fn main() { ``` -Cargo a généré un programme *Hello, world!* pour vous, exactement comme celui +Cargo a généré un programme “Hello, world!” pour vous, exactement comme celui que nous avons écrit dans l'encart 1-1 ! Pour le moment, les seules différences entre notre projet précédent et le projet que Cargo a généré sont que Cargo a placé le code dans le dossier *src*, et que nous avons un fichier de @@ -247,14 +247,14 @@ pas directement relié à votre code. Utiliser Cargo vous aide à structurer vos projets. Il y a un endroit pour tout, et tout est à sa place. Si vous commencez un projet sans utiliser Cargo, comme nous l'avons fait avec -le projet *Hello, world!*, vous pouvez le transformer en projet qui +le projet “Hello, world!”, vous pouvez le transformer en projet qui utilise Cargo. Déplacez le code de votre projet dans un dossier *src* et créez un fichier *Cargo.toml* adéquat. @@ -265,13 +265,13 @@ un fichier *Cargo.toml* adéquat. ### Compiler et exécuter un projet Cargo Maintenant, regardons ce qu'il y a de différent quand nous compilons et -exécutons le programme *Hello, world!* avec Cargo ! À l'intérieur de votre +exécutons le programme “Hello, world!” avec Cargo ! À l'intérieur de votre dossier *hello_cargo*, compilez votre projet en utilisant la commande suivante : ```text @@ -524,14 +524,14 @@ avez appris comment : * Install the latest stable version of Rust using `rustup` * Update to a newer Rust version * Open locally installed documentation -* Write and run a Hello, world! program using `rustc` directly +* Write and run a “Hello, world!” program using `rustc` directly * Create and run a new project using the conventions of Cargo --> * Installer la dernière version stable de Rust en utilisant `rustup` * Mettre à jour Rust vers une nouvelle version * Ouvrir la documentation installée en local -* Écrire et exécuter un programme *Hello, world!* en utilisant directement +* Écrire et exécuter un programme “Hello, world!” en utilisant directement `rustc` * Créer et exécuter un nouveau projet en utilisant les conventions de Cargo diff --git a/FRENCH/src/ch02-00-guessing-game-tutorial.md b/FRENCH/src/ch02-00-guessing-game-tutorial.md index 6c5a91b0a2..b33dcf1575 100644 --- a/FRENCH/src/ch02-00-guessing-game-tutorial.md +++ b/FRENCH/src/ch02-00-guessing-game-tutorial.md @@ -455,7 +455,7 @@ io::stdin().read_line(&mut supposition) ``` + @@ -884,7 +890,7 @@ l'en-tête de section `[dependencies]` que Cargo a créé pour vous : ```toml [dependencies] -rand = "0.3.14" +rand = "0.5.5" ``` Dans le fichier *Cargo.toml*, tout ce qui suit une en-tête fait partie de cette @@ -904,11 +910,11 @@ section, et ce jusqu'à ce qu'une autre section débute. La section `[dependencies]` permet d'indiquer à Cargo de quelles *crates* externes votre projet dépend, et de quelle version de ces *crates* vous avez besoin. Dans notre cas, on ajoute comme dépendance la crate `rand` avec la version -sémantique `0.3.14`. Cargo arrive à interpréter le +sémantique `0.5.5`. Cargo arrive à interpréter le [versionnage sémantique][semver] (aussi appelé *SemVer*), qui -est une convention d'écriture de numéros de version. En réalité, `0.3.14` est -une abréviation pour `^0.3.14`, ce qui signifie “toute version qui propose une -API publique compatible avec la version 0.3.14”. +est une convention d'écriture de numéros de version. En réalité, `0.5.5` est +une abréviation pour `^0.5.5`, ce qui signifie “toute version qui propose une +API publique compatible avec la version 0.5.5”. [semver]: http://semver.org @@ -922,13 +928,19 @@ du projet, comme dans l'encart 2-2 : ```text $ cargo build - Updating registry `https://github.com/rust-lang/crates.io-index` - Downloading rand v0.3.14 - Downloading libc v0.2.14 - Compiling libc v0.2.14 - Compiling rand v0.3.14 + Updating crates.io index + Downloaded rand v0.5.5 + Downloaded libc v0.2.62 + Downloaded rand_core v0.2.2 + Downloaded rand_core v0.3.1 + Downloaded rand_core v0.4.2 + Compiling rand_core v0.4.2 + Compiling libc v0.2.62 + Compiling rand_core v0.3.1 + Compiling rand_core v0.2.2 + Compiling rand v0.5.5 Compiling guessing_game v0.1.0 (file:///projects/guessing_game) - Finished dev [unoptimized + debuginfo] target(s) in 2.53 secs + Finished dev [unoptimized + debuginfo] target(s) in 2.53 s ``` Une fois le registre mis à jour, Cargo lit la section `[dependencies]` et se charge de télécharger les *crates* que vous n'avez pas encore. Dans notre cas, bien que nous n'ayons spécifié qu'une seule dépendance, `rand`, Cargo a aussi -téléchargé la *crate* `libc`, car `rand` dépend de `libc` pour fonctionner. Une -fois le téléchargement terminé des *crates*, Rust les compile, puis compile -notre projet avec les dépendances disponibles. +téléchargé la *crate* `libc` et `rand_core`, car `rand` dépend d'elles pour +fonctionner. Une fois le téléchargement terminé des *crates*, Rust les compile, +puis compile notre projet avec les dépendances disponibles. @@ -1042,7 +1054,7 @@ Cargo embarque une fonctionnalité qui garantie que vous pouvez recompiler le même artéfact à chaque fois que vous ou quelqu'un d'autre compile votre code : Cargo va utiliser uniquement les versions de dépendances que vous avez utilisées jusqu'à ce que vous indiquiez le contraire. -Par exemple, que se passe-t-il si la semaine prochaine, la version 0.3.15 de la +Par exemple, que se passe-t-il si la semaine prochaine, la version 0.5.6 de la *crate* `rand` est publiée et qu'elle apporte une correction importante, mais aussi qu'elle produit une régression qui va casser votre code ? @@ -1055,7 +1067,7 @@ the *Cargo.lock* file. When you build your project in the future, Cargo will see that the *Cargo.lock* file exists and use the versions specified there rather than doing all the work of figuring out versions again. This lets you have a reproducible build automatically. In other words, your project will -remain at `0.3.14` until you explicitly upgrade, thanks to the *Cargo.lock* +remain at `0.5.5` until you explicitly upgrade, thanks to the *Cargo.lock* file. --> @@ -1068,7 +1080,7 @@ Quand vous recompilerez votre projet plus tard, Cargo verra que le fichier *Cargo.lock* existe et utilisera les versions précisées à l'intérieur au lieu de recommencer à déterminer toutes les versions demandées. Ceci vous permet d'avoir automatiquement des compilations reproductibles. -En d'autres termes, votre projet va rester sur la version `0.3.14` jusqu'à ce +En d'autres termes, votre projet va rester sur la version `0.5.5` jusqu'à ce que vous le mettiez à jour explicitement, grâce au fichier *Cargo.lock*. Mais par défaut, Cargo va rechercher uniquement les versions plus grandes que -`0.3.0` et inférieures à `0.4.0`. Si la *crate* `rand` a été publiée en deux -nouvelles versions, `0.3.15` et `0.4.0`, alors vous verrez ceci si vous +`0.5.5` et inférieures à `0.6.0`. Si la *crate* `rand` a été publiée en deux +nouvelles versions, `0.5.6` et `0.6.0`, alors vous verrez ceci si vous lancez `cargo update` : ```text $ cargo update - Updating registry `https://github.com/rust-lang/crates.io-index` - Updating rand v0.3.14 -> v0.3.15 + Updating crates.io index + Updating rand v0.5.5 -> v0.5.6 ``` À partir de ce moment, vous pouvez aussi constater un changement dans le fichier *Cargo.lock* indiquant que la version de la *crate* `rand` que vous utilisez -maintenant est la `0.3.15`. +maintenant est la `0.5.6`. @@ -1127,8 +1139,7 @@ ceci : ```toml [dependencies] - -rand = "0.4.0" +rand = "0.6.0" ``` Un *tuple* est une manière générale de regrouper plusieurs valeurs @@ -692,13 +692,13 @@ fn main() { Ce programme crée un tuple, `x`, puis crée une nouvelle variable pour -chaque élément en utilisant leur indice. Comme dans de nombreux langages de -programmation, le premier indice d'un tuple est 0. +chaque élément en utilisant leur indices respectifs. Comme dans de nombreux +langages de programmation, le premier indice d'un tuple est 0. Un exemple de cas où vous pourriez avoir recours à un tableau plutôt qu'à un @@ -800,7 +800,7 @@ let a: [i32; 5] = [1, 2, 3, 4, 5]; Ici, `i32` est le type de chaque élément. Après le point-virgule, le nombre `5` From e9acc2b3a7acf9f69b90837cc7f88d0efc94ad7d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=ABl=20J=2E=20Pr=C3=A9sent?= <36854931+joeljpresent@users.noreply.github.com> Date: Tue, 5 Nov 2019 13:42:58 +0100 Subject: [PATCH 110/117] Refine markdownlint config Restrict deactivation of MD013 (line length) to headings, tables and code blocks; note that this could produce false positives for comments, links followed by `` and long HTML tags. Restrict deactivation of MD033 (inline HTML tags) to tags that are actually used: ``, `` and ``. Remove deactivation of MD038 and MD046 which was unnecessary. --- .vscode/settings.json | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/.vscode/settings.json b/.vscode/settings.json index 65b5a0cb95..4a964f40f7 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -4,12 +4,16 @@ "MD001": false, "MD002": false, "MD007": false, - "MD013": false, + "MD013": { + "headings": false, + "tables": false, + "code_blocks": false + }, "MD014": false, "MD026": false, - "MD033": false, - "MD038": false, - "MD041": false, - "MD046": false + "MD033": { + "allowed_elements": ["img", "span", "sup"] + }, + "MD041": false } } From 3b2c4806260fce73992ea8a608cf62b8b16cf31b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=ABl=20J=2E=20Pr=C3=A9sent?= <36854931+joeljpresent@users.noreply.github.com> Date: Thu, 7 Nov 2019 12:08:47 +0100 Subject: [PATCH 111/117] Proofread ch04-02 --- FRENCH/src/SUMMARY.md | 1 - .../src/ch04-02-references-and-borrowing.md | 123 +++++++++--------- FRENCH/src/img/trpl04-05.svg | 20 +-- FRENCH/src/translation-terms.md | 2 +- 4 files changed, 72 insertions(+), 74 deletions(-) diff --git a/FRENCH/src/SUMMARY.md b/FRENCH/src/SUMMARY.md index ef8b829ed3..4305682b80 100644 --- a/FRENCH/src/SUMMARY.md +++ b/FRENCH/src/SUMMARY.md @@ -23,7 +23,6 @@ - [Comprendre la possession](ch04-00-understanding-ownership.md) - [Qu'est-ce que la possession ?](ch04-01-what-is-ownership.md) - - [Les références et l'emprunt](ch04-02-references-and-borrowing.md) - [Utiliser les structures pour structurer des données apparentées](ch05-00-structs.md) diff --git a/FRENCH/src/ch04-02-references-and-borrowing.md b/FRENCH/src/ch04-02-references-and-borrowing.md index 6e012f6aff..afbe43bbbb 100644 --- a/FRENCH/src/ch04-02-references-and-borrowing.md +++ b/FRENCH/src/ch04-02-references-and-borrowing.md @@ -13,8 +13,8 @@ call to `calculate_length`, because the `String` was moved into La difficulté avec le code du tuple à la fin de la section précédente est que nous avons besoin de retourner la `String` au code appelant pour qu'il puisse -continuer à utiliser la `String` après l'appel à `calculer_longueur`, car la -`String` a été déplacée dans `calculer_longueur`. +continuer à utiliser la `String` après l'appel à `calculer_taille`, car la +`String` a été déplacée dans `calculer_taille`. -Voici comment déclarer et utiliser une fonction `calculer_longueur` qui prend -une *référence* à un objet en paramètre plutôt que de prendre possession de la +Voici comment définir et utiliser une fonction `calculer_taille` qui prend une +*référence* à un objet en paramètre plutôt que de prendre possession de la valeur : ```rust -# fn calculer_longueur(s: &String) -> usize { +# fn calculer_taille(s: &String) -> usize { # s.len() # } let s1 = String::from("hello"); -let long = calculer_longueur(&s1); +let long = calculer_taille(&s1); ``` La syntaxe `&s1` nous permet de créer une référence qui se *réfère* à la valeur -de `s1` mais n'en pas possession. Et comme elle n'en pas possession, la valeur -sur laquelle elle pointe désigne ne sera pas libérée quand cette référence +de `s1` mais n'en prend pas possession. Et comme elle ne la possède pas, la +valeur vers laquelle elle pointe ne sera pas libérée quand cette référence sortira de la portée. ```rust -fn calculer_longueur(s: &String) -> usize { // s est une référence à une String +fn calculer_taille(s: &String) -> usize { // s est une référence à une String s.len() -} // Ici, s sort de la portée. Mais comme elle ne prend pas possession ce dont +} // Ici, s sort de la portée. Mais comme elle ne prend pas possession de ce // à quoi elle fait référence, il ne se passe rien. ``` @@ -178,7 +178,7 @@ order to give back ownership, because we never had ownership. La portée dans laquelle la variable `s` est en vigueur est la même que toute portée d'un paramètre de fonction, mais nous ne libérons pas ce sur quoi cette -référence pointe quand elle sort de la portée, car nous ne nous n'en prenons pas +référence pointe quand elle sort de la portée, car nous n'en prenons pas possession. Lorsque les fonctions ont des références en paramètres au lieu des valeurs réelles, nous n'avons pas besoin de retourner les valeurs pour les rendre, car nous n'en avons jamais pris possession. @@ -191,8 +191,8 @@ have to give it back. Quand nous avons des références dans les paramètres d'une fonction, nous appelons cela *l'emprunt*. Comme dans la vie réelle, quand un objet appartient -à quelqu'un, vous pouvez lui emprunter. Et quand vous avez fini, vous devez lui -rendre. +à quelqu'un, vous pouvez le lui emprunter. Et quand vous avez fini, vous devez +le lui rendre. -D'abord, nous avons dû modifier `s` pour être `mut`. Ensuite, nous avons dû +D'abord, nous avons dû préciser que `s` est `mut`. Ensuite, nous avons dû créer une référence mutable avec `&mut s` et accepter de prendre une référence mutable avec `texte: &mut String`. @@ -406,7 +406,7 @@ these three behaviors occur: --> L'avantage d'avoir cette contrainte est que Rust peut empêcher les accès -concurrent au moment de la compilation. Un *accès concurrent* est une situation +concurrents au moment de la compilation. Un *accès concurrent* est une situation de concurrence qui se produit lorsque ces trois facteurs se combinent : -L'accès concurrent provoque des comportements incontrôlés et rend difficile le +L'accès concurrent provoque des comportements indéfinis et rend difficile le diagnostic et la résolution de problèmes lorsque vous essayez de les reproduire -au moment de l'exécution; Rust évite ce problème parce qu'il ne va pas compiler -le code avec un accès concurrent ! +au moment de l'exécution ; Rust évite ce problème parce qu'il ne va pas compiler +du code avec des accès concurrents ! Comme d'habitude, nous pouvons utiliser des accolades pour créer une nouvelle -portée, pour nous permettre d'avoir plusieurs références mutables, mais pas en -*simultané* : +portée, pour nous permettre d'avoir plusieurs références mutables, mais pas +*en même temps* : Les portées des références immuables `r1` et `r2` se terminent après le -`println!` où elles sont utilisées pour la dernière fois, qui se situe avant que +`println!` où elles sont utilisées pour la dernière fois, c'est-à-dire avant que la référence mutable `r3` soit créée. Ces portées ne se chevauchent pas, donc ce code est autorisé. @@ -605,17 +605,17 @@ than at runtime) and showing you exactly where the problem is. Then you don’t have to track down why your data isn’t what you thought it was. --> -Même si ces erreurs d'emprunt peuvent parfois être frustrantes, souvenez-vous -que le compilateur de Rust nous fait signale un potentiel bogue avant l'heure -(au moment de la compilation plutôt que l'exécution) et vous montre où est -exactement le problème. Ainsi, vous n'avez plus à chercher pourquoi vos données -ne correspondent pas à ce que vous pensiez qu'elles devraient être. +Même si ces erreurs d'emprunt peuvent parfois être frustrantes, n'oubliez pas +que le compilateur de Rust nous signale un bogue potentiel en avance (au moment +de la compilation plutôt que l'exécution) et vous montre où se situe exactement +le problème. Ainsi, vous n'avez pas à chercher pourquoi vos données ne +correspondent pas à ce que vous pensiez qu'elles devraient être. -### Les références sautillantes +### Les références pendouillantes Avec les langages qui utilisent les pointeurs, il est facile de créer par erreur -un *pointeur sautillant*, qui est un pointeur qui désigne un endroit dans la -mémoire qui a été donné à quelqu'un d'autre, en libérant de la mémoire tout en -conservant un pointeur vers cette mémoire. En revanche, avec Rust, le -compilateur garantit que les références ne seront jamais des références -sautillantes : si nous avons une référence vers des données, le compilateur va +un *pointeur pendouillant* (*dangling pointer*), qui est un pointeur qui pointe +vers un emplacement mémoire qui a été donné à quelqu'un d'autre, en libérant de +la mémoire tout en conservant un pointeur vers cette mémoire. En revanche, avec +Rust, le compilateur garantit que les références ne seront jamais des références +pendouillantes : si nous avons une référence vers une donnée, le compilateur va s'assurer que cette donnée ne va pas sortir de la portée avant que la référence vers cette donnée en soit elle-même sortie. @@ -641,7 +641,7 @@ Let’s try to create a dangling reference, which Rust will prevent with a compile-time error: --> -Essayons de créer une référence sautillante, que Rust va empêcher avec une +Essayons de créer une référence pendouillante, ce que Rust va empêcher avec une erreur au moment de la compilation : main.rs:5:16 | -5 | fn sautillante() -> &String { - | ^ expected lifetime parameter +5 | fn pendouille() -> &String { + | ^ expected lifetime parameter | = help: this function's return type contains a borrowed value, but there is no value for it to be borrowed from @@ -715,9 +715,9 @@ about lifetimes, the message does contain the key to why this code is a problem: --> Ce message d'erreur fait référence à une fonctionnalité que nous n'avons pas -encore vu : les *durées de vie*. Nous allons aborder les durées de vie dans le -chapitre 10. Mais, si vous mettez de côté les parties qui parlent de la durée de -vie, le message donne la clé de la raison qui pose problème : +encore vue : les *durées de vie*. Nous aborderons les durées de vie dans le +chapitre 10. Mais, si vous mettez de côté les parties qui parlent de durées de +vie, le message explique pourquoi le code pose problème : Regardons de plus près ce qui se passe exactement à chaque étape de notre code -de `sautillante` : +de `pendouille` : - ```rust,ignore,does_not_compile -fn sautillante() -> &String { // sautillante retourne une référence vers un String +fn pendouille() -> &String { // pendouille retourne une référence vers une String let s = String::from("hello"); // s est une nouvelle String &s // nous retournons une référence vers la String, s -} // Ici, s sort de la portée, et est libéré. Sa mémoire disparait. C'est dangereux ! +} // Ici, s sort de la portée, et est libéré. Sa mémoire disparaît. + // Attention, danger ! ``` -Comme `s` est créé dans `sautillante`, lorsque le code de `sautillante` est -terminé, `s` va être désallouée. Mais nous avons essayé de retourner une -référence vers elle. Cela veut dire que cette référence va pointer vers une +Comme `s` est créé dans `pendouille`, lorsque le code de `pendouille` est +terminé, la variable `s` sera désallouée. Mais nous avons essayé de retourner +une référence vers elle. Cela veut dire que cette référence va pointer vers une `String` invalide. Ce n'est pas bon ! Rust ne nous laissera pas faire cela. ```rust -fn pas_sautillante() -> String { +fn ne_pendouille_pas() -> String { let s = String::from("hello"); s @@ -815,8 +815,8 @@ This works without any problems. Ownership is moved out, and nothing is deallocated. --> -Cela fonctionne sans problème. La possession est déplacée, et rien n'est -désalloué. +Cela fonctionne sans problème. La possession est transférée à la valeur de +retour de la fonction, et rien n'est désalloué. -* Au même moment, vous pouvez avoir *soit* une référence mutable, *soit* un +* À un instant donné, vous pouvez avoir *soit* une référence mutable, *soit* un nombre quelconque de références immuables. * Les références doivent toujours être en vigueur. @@ -844,5 +844,4 @@ Récapitulons ce que nous avons vu à propos des références : Next, we’ll look at a different kind of reference: slices. --> -A l'étape suivante, nous allons aborder un autre type de référence : les -découpages. +Ensuite, nous aborderons un autre type de référence : les *slices*. diff --git a/FRENCH/src/img/trpl04-05.svg b/FRENCH/src/img/trpl04-05.svg index b4bf2ebee8..21768601b7 100644 --- a/FRENCH/src/img/trpl04-05.svg +++ b/FRENCH/src/img/trpl04-05.svg @@ -15,11 +15,11 @@ s -name +nom -value +valeur -ptr +pointeur @@ -28,18 +28,18 @@ s1 -name +nom -value +valeur -ptr +pointeur -len +taille 5 -capacity +capacité 5 @@ -53,9 +53,9 @@ table2 -index +indice -value +valeur 0 diff --git a/FRENCH/src/translation-terms.md b/FRENCH/src/translation-terms.md index b683259d8c..c4fa27b614 100644 --- a/FRENCH/src/translation-terms.md +++ b/FRENCH/src/translation-terms.md @@ -47,7 +47,7 @@ français. | crash | plantage | - | | crate | crate | nom féminin (une *crate*) | | curly bracket | accolade | - | -| dangling (reference) | (référence) sautillante | - | +| dangling | pendouillant | - | | data race | accès concurrent | - | | data representation | modèle de données | - | | deallocate | désalloué | - | From 43dff063f7562d1e0adfd739550209448085a7cf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=ABl=20J=2E=20Pr=C3=A9sent?= <36854931+joeljpresent@users.noreply.github.com> Date: Fri, 8 Nov 2019 10:52:37 +0100 Subject: [PATCH 112/117] Fix Markdownlint warnings --- FRENCH/src/ch00-00-introduction.md | 2 + FRENCH/src/ch01-01-installation.md | 3 +- FRENCH/src/ch01-02-hello-world.md | 1 - FRENCH/src/ch02-00-guessing-game-tutorial.md | 13 ++++-- .../src/ch03-01-variables-and-mutability.md | 4 +- FRENCH/src/ch03-02-data-types.md | 6 ++- FRENCH/src/ch03-03-how-functions-work.md | 3 +- FRENCH/src/ch03-05-control-flow.md | 7 ++- FRENCH/src/ch04-01-what-is-ownership.md | 43 +++++++++++++++---- 9 files changed, 58 insertions(+), 24 deletions(-) diff --git a/FRENCH/src/ch00-00-introduction.md b/FRENCH/src/ch00-00-introduction.md index aca4e42801..7e1e09db70 100644 --- a/FRENCH/src/ch00-00-introduction.md +++ b/FRENCH/src/ch00-00-introduction.md @@ -443,6 +443,7 @@ il ne compile pas ! Assurez-vous d'avoir lu le texte autour pour savoir si l'exemple que vous tentez de compiler doit échouer. Ferris va aussi vous aider à identifier du code qui ne devrait pas fonctionner : + + | Ferris | Signification | |------------------------------------------------------------------------|--------------------------------------------------| diff --git a/FRENCH/src/ch01-01-installation.md b/FRENCH/src/ch01-01-installation.md index d212f2668a..19acb266ee 100644 --- a/FRENCH/src/ch01-01-installation.md +++ b/FRENCH/src/ch01-01-installation.md @@ -178,7 +178,8 @@ les outils de compilation est d'installer [install]: https://www.rust-lang.org/tools/install diff --git a/FRENCH/src/ch01-02-hello-world.md b/FRENCH/src/ch01-02-hello-world.md index 4d178989ba..a198925c95 100644 --- a/FRENCH/src/ch01-02-hello-world.md +++ b/FRENCH/src/ch01-02-hello-world.md @@ -81,7 +81,6 @@ For Windows CMD, enter this: Avec CMD sous Windows, écrivez ceci : - ```cmd > mkdir "%USERPROFILE%\projects" > cd /d "%USERPROFILE%\projects" diff --git a/FRENCH/src/ch02-00-guessing-game-tutorial.md b/FRENCH/src/ch02-00-guessing-game-tutorial.md index b33dcf1575..b2758a51b8 100644 --- a/FRENCH/src/ch02-00-guessing-game-tutorial.md +++ b/FRENCH/src/ch02-00-guessing-game-tutorial.md @@ -1529,6 +1529,7 @@ However, the code in Listing 2-4 won’t compile yet. Let’s try it: Cependant, notre code dans l'encart 2-4 ne compile pas encore. Essayons de le faire : + + ```text $ cargo build @@ -1769,7 +1771,8 @@ L'utilisation de `parse` peut facilement mener à une erreur. Si par exemple, le texte contient `A👍%`, il ne sera pas possible de le convertir en nombre. Comme elle peut échouer, la méthode `parse` retourne un type `Result`, comme celui que la méthode `read_line` retourne (comme nous l'avons vu plus tôt dans -[“Gérer les erreurs potentielles avec le type `Result`”](#gérer-les-erreurs-potentielles-avec-le-type-result)). +[“Gérer les erreurs potentielles avec le type +`Result`”](#gérer-les-erreurs-potentielles-avec-le-type-result)). Nous allons gérer ce `Result` de la même manière, avec à nouveau la méthode `expect`. Si `parse` retourne une variante `Err` de `Result` car elle ne peut pas créer un nombre à partir de la chaîne de caractères, l'appel à @@ -1922,11 +1925,12 @@ user can take advantage of that in order to quit, as shown here: L'utilisateur pourrait quand même interrompre le programme en utilisant le raccourci clavier ctrl-c. Mais il y a une autre façon d'échapper à ce monstre insatiable, comme nous -l'avons abordé dans la partie -[“Comparer le nombre saisi au nombre secret”](#comparer-le-nombre-saisi-au-nombre-secret) : -si l'utilisateur saisit quelque chose qui n'est pas un nombre, le programme va +l'avons abordé dans la partie [“Comparer le nombre saisi au nombre +secret”](#comparer-le-nombre-saisi-au-nombre-secret) : si +l'utilisateur saisit quelque chose qui n'est pas un nombre, le programme va planter. L'utilisateur peut procéder ainsi pour le quitter, comme ci-dessous : + + ```text $ cargo run diff --git a/FRENCH/src/ch03-01-variables-and-mutability.md b/FRENCH/src/ch03-01-variables-and-mutability.md index 768501f912..517438d957 100644 --- a/FRENCH/src/ch03-01-variables-and-mutability.md +++ b/FRENCH/src/ch03-01-variables-and-mutability.md @@ -375,8 +375,8 @@ can shadow a variable by using the same variable’s name and repeating the use of the `let` keyword as follows: --> -Comme nous l'avons vu dans la section -[“Comparer le nombre saisi au nombre secret”][comparing-the-guess-to-the-secret-number] +Comme nous l'avons vu dans la section [“Comparer le nombre saisi au nombre +secret”][comparing-the-guess-to-the-secret-number] du jeu de devinettes au chapitre 2, on peut déclarer une nouvelle variable avec le même nom qu'une variable précédente, et la nouvelle variable masquera la première. Les Rustacés disent que la première variable est *masquée* diff --git a/FRENCH/src/ch03-02-data-types.md b/FRENCH/src/ch03-02-data-types.md index 0588775cfe..3aabb10eba 100644 --- a/FRENCH/src/ch03-02-data-types.md +++ b/FRENCH/src/ch03-02-data-types.md @@ -31,7 +31,8 @@ compilation. Le compilateur peut souvent déduire quel type utiliser en se basan sur la valeur et sur la façon dont elle est utilisée. Dans les cas où plusieurs types sont envisageables, comme lorsque nous avons converti une chaîne de caractères en un type numérique en utilisant `parse` dans la section -[“Comparer le nombre saisi au nombre secret”][comparing-the-guess-to-the-secret-number] +[“Comparer le nombre saisi au nombre +secret”][comparing-the-guess-to-the-secret-number] du chapitre 2, nous devons ajouter une annotation de type, comme ceci : Chaque variante peut-être signée ou non signée et possède une taille explicite. diff --git a/FRENCH/src/ch03-03-how-functions-work.md b/FRENCH/src/ch03-03-how-functions-work.md index 27ddb48c3d..50b283451e 100644 --- a/FRENCH/src/ch03-03-how-functions-work.md +++ b/FRENCH/src/ch03-03-how-functions-work.md @@ -380,7 +380,8 @@ fn main() { ``` Encart 3-1 : une fonction `main` qui contient une diff --git a/FRENCH/src/ch03-05-control-flow.md b/FRENCH/src/ch03-05-control-flow.md index a32a96decb..9ba2f10f2a 100644 --- a/FRENCH/src/ch03-05-control-flow.md +++ b/FRENCH/src/ch03-05-control-flow.md @@ -742,10 +742,9 @@ guessing the correct number. Heureusement, Rust fournit un autre moyen, plus fiable, de sortir d'une boucle. Vous pouvez ajouter le mot-clé `break` à l'intérieur de la boucle pour demander au programme d'arrêter la boucle. Souvenez-vous que nous avions fait ceci dans -le jeu de devinettes, dans la section -[“Arrêter le programme après avoir gagné”][quitting-after-a-correct-guess] -du chapitre 2 afin de quitter le programme quand l'utilisateur gagne le jeu en -devinant le bon nombre. +le jeu de devinettes, dans la section [“Arrêter le programme après avoir +gagné”][quitting-after-a-correct-guess] du chapitre 2 afin de +quitter le programme quand l'utilisateur gagne le jeu en devinant le bon nombre. du chapitre 5 et lorsque nous aborderons les espaces de noms dans la section -[“Les chemins pour désigner un élément dans l'arborescence de module”][paths-module-tree] -du chapitre 7. +[“Les chemins pour désigner un élément dans l'arborescence de +module”][paths-module-tree] du chapitre 7. + +Une string en mémoire + +s1 et s2 qui pointent vers la même valeur + +s1 et s2 à deux endroits + +s1 déplacé dans s2 Si nous *voulons* faire une copie profonde des données sur le tas d'une -`String`, et pas seulement des données sur la pile, nous pouvons utiliser une +`String`, et pas seulement des données sur la pile, nous pouvons utiliser une méthode commune qui s'appelle `clone`. Nous aborderons la syntaxe des méthodes au chapitre 5, mais comme les méthodes sont des outils courants dans de nombreux langages, vous les avez probablement utilisées auparavant. @@ -1048,7 +1072,7 @@ fn makes_copy(some_integer: i32) { // some_integer comes into scope --> ```rust -fn main() { +fn main() { let s = String::from("hello"); // s rentre dans la portée. prendre_possession(s); // La valeur de s est déplacée dans la fonction… @@ -1281,7 +1305,8 @@ c'est ce qu'on appelle les *références*. [data-types]: ch03-02-data-types.html#data-types [derivable-traits]: appendix-03-derivable-traits.html [method-syntax]: ch05-03-method-syntax.html#method-syntax -[paths-module-tree]: ch07-03-paths-for-referring-to-an-item-in-the-module-tree.html +[paths-module-tree]: +ch07-03-paths-for-referring-to-an-item-in-the-module-tree.html --> [data-types]: ch03-02-data-types.html From d91cfd821000bb11323df9f91c8193f553cb376e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=ABl=20J=2E=20Pr=C3=A9sent?= <36854931+joeljpresent@users.noreply.github.com> Date: Fri, 8 Nov 2019 11:18:52 +0100 Subject: [PATCH 113/117] Fix figure 4-5 in ch04-02 --- FRENCH/src/ch04-02-references-and-borrowing.md | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/FRENCH/src/ch04-02-references-and-borrowing.md b/FRENCH/src/ch04-02-references-and-borrowing.md index afbe43bbbb..c6b753b551 100644 --- a/FRENCH/src/ch04-02-references-and-borrowing.md +++ b/FRENCH/src/ch04-02-references-and-borrowing.md @@ -83,7 +83,13 @@ Ces esperluettes sont des *références*, et elles permettent de vous référer une valeur sans en prendre possession. L'illustration 4-5 nous montre cela dans un schéma. -&String s qui pointe vers la String s1 + + +&String s qui pointe vers la String s1 + + +[install]: https://www.rust-lang.org/tools/install [visualstudio]: https://www.visualstudio.com/fr/downloads/#build-tools-for-visual-studio-2019 + Chaque variante peut-être signée ou non signée et possède une taille explicite. *Signé* et *non signé* veut dire respectivement que le nombre peut prendre ou diff --git a/FRENCH/src/ch03-03-how-functions-work.md b/FRENCH/src/ch03-03-how-functions-work.md index 50b283451e..f01ddc9883 100644 --- a/FRENCH/src/ch03-03-how-functions-work.md +++ b/FRENCH/src/ch03-03-how-functions-work.md @@ -379,10 +379,11 @@ fn main() { } ``` + + Encart 3-1 : une fonction `main` qui contient une instruction diff --git a/FRENCH/src/ch04-01-what-is-ownership.md b/FRENCH/src/ch04-01-what-is-ownership.md index b68c4ba946..34f0df038c 100644 --- a/FRENCH/src/ch04-01-what-is-ownership.md +++ b/FRENCH/src/ch04-01-what-is-ownership.md @@ -663,10 +663,11 @@ un pointeur vers la mémoire qui contient le contenu de la chaîne de caractère une taille, et une capacité. Ce groupe de données est stocké sur la pile. À droite, nous avons la mémoire sur le tas qui contient les données. + + Une string en mémoire @@ -706,10 +707,11 @@ stockés sur la pile. Nous ne copions pas les données stockées sur le tas auxquelles le pointeur se réfère. Autrement dit, la représentation des données dans la mémoire ressemble à l'illustration 4-2. + + s1 et s2 qui pointent vers la même valeur @@ -735,10 +737,11 @@ mémoire si Rust avait aussi copié les données sur le tas. Si Rust faisait cec l'opération `s2 = s1` pourrait potentiellement être très coûteuse en termes de performances d'exécution si les données sur le tas étaient volumineuses. + + s1 et s2 à deux endroits @@ -833,10 +836,11 @@ lieu d'appeler cela une copie superficielle, on appelle cela un *déplacement*. Ici, nous pourrions dire que `s1` a été *déplacé* dans `s2`. Donc ce qui se passe réellement est décrit par l'illustration 4-4. + + s1 déplacé dans s2 @@ -1301,13 +1305,14 @@ Mais c'est trop laborieux et beaucoup de travail pour un principe qui devrait être banal. Heureusement pour nous, Rust a une fonctionnalité pour ce principe, c'est ce qu'on appelle les *références*. + + [data-types]: ch03-02-data-types.html [derivable-traits]: appendix-03-derivable-traits.html From 2d5140c6cf6932fd2513017fa2a842f95aa745d9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=ABl=20J=2E=20Pr=C3=A9sent?= <36854931+joeljpresent@users.noreply.github.com> Date: Sat, 9 Nov 2019 09:27:03 +0100 Subject: [PATCH 115/117] Use markdownlint-disable|restore for English Figure 4-5 --- FRENCH/src/ch04-02-references-and-borrowing.md | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/FRENCH/src/ch04-02-references-and-borrowing.md b/FRENCH/src/ch04-02-references-and-borrowing.md index c6b753b551..8f9a7572f4 100644 --- a/FRENCH/src/ch04-02-references-and-borrowing.md +++ b/FRENCH/src/ch04-02-references-and-borrowing.md @@ -83,10 +83,11 @@ Ces esperluettes sont des *références*, et elles permettent de vous référer une valeur sans en prendre possession. L'illustration 4-5 nous montre cela dans un schéma. + + &String s qui pointe vers la String s1 From b99c09c276c852417275fdda684100c17169cb69 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=ABl=20J=2E=20Pr=C3=A9sent?= <36854931+joeljpresent@users.noreply.github.com> Date: Sun, 10 Nov 2019 09:31:01 +0100 Subject: [PATCH 116/117] Translate SVG figues properly --- FRENCH/CONTRIBUTING.md | 23 ++++- FRENCH/dot/trpl04-01.dot | 26 +++++ FRENCH/dot/trpl04-02.dot | 35 +++++++ FRENCH/dot/trpl04-03.dot | 44 +++++++++ FRENCH/dot/trpl04-04.dot | 35 +++++++ FRENCH/dot/trpl04-05.dot | 32 +++++++ FRENCH/dot/trpl04-06.dot | 41 ++++++++ FRENCH/src/img/trpl04-01.svg | 92 +++++++++--------- FRENCH/src/img/trpl04-02.svg | 130 ++++++++++++------------- FRENCH/src/img/trpl04-03.svg | 178 +++++++++++++++++------------------ FRENCH/src/img/trpl04-04.svg | 132 +++++++++++++------------- FRENCH/src/img/trpl04-05.svg | 87 +++++++++++++++++ FRENCH/src/img/trpl04-06.svg | 115 ++++++++++++++++++++++ FRENCH/src/img/trpl15-01.svg | 43 +++++++++ FRENCH/src/img/trpl15-02.svg | 26 +++++ FRENCH/src/img/trpl15-03.svg | 109 +++++++++++++++++++++ FRENCH/src/img/trpl15-04.svg | 55 +++++++++++ 17 files changed, 935 insertions(+), 268 deletions(-) create mode 100644 FRENCH/dot/trpl04-01.dot create mode 100644 FRENCH/dot/trpl04-02.dot create mode 100644 FRENCH/dot/trpl04-03.dot create mode 100644 FRENCH/dot/trpl04-04.dot create mode 100644 FRENCH/dot/trpl04-05.dot create mode 100644 FRENCH/dot/trpl04-06.dot create mode 100644 FRENCH/src/img/trpl04-05.svg create mode 100644 FRENCH/src/img/trpl04-06.svg create mode 100644 FRENCH/src/img/trpl15-01.svg create mode 100644 FRENCH/src/img/trpl15-02.svg create mode 100644 FRENCH/src/img/trpl15-03.svg create mode 100644 FRENCH/src/img/trpl15-04.svg diff --git a/FRENCH/CONTRIBUTING.md b/FRENCH/CONTRIBUTING.md index 3c992e5e0f..6650b71d95 100644 --- a/FRENCH/CONTRIBUTING.md +++ b/FRENCH/CONTRIBUTING.md @@ -14,6 +14,7 @@ when you need to translate a technicial term. ### Translation of Rust code In rust code, we should translate : + - comment - string text - variable name @@ -45,7 +46,7 @@ instead of space on punctuation who need this space before (like `:`, `!`, `?`, ### Translate flow *NB : the following term `main translate repository` refers to -https://github.com/Jimskapt/rust-book-fr* +* 01. Open or edit an GitHub issue in the *main translate repository* to report to other that you are working on `ch00-00-introduction`. @@ -101,7 +102,7 @@ https://github.com/Jimskapt/rust-book-fr* repository*) 03. `git merge english-book/master` (merging latest changes from *English main repository* on current branch) - + It is also the same to update your fork with the main translate repository. ### Add a translation term @@ -113,3 +114,21 @@ It is also the same to update your fork with the main translate repository. 02. Edit the `/FRENCH/src/translation-terms.md` file with your new technical term translation. Write it in singular and if necessary, specify the gender of the translation in `Remarques` column. + +### Translate figures + +Let's suppose you want to translate Figure 42-69. +You need to have the `dot` installed, for instance after typing +`sudo apt install graphviz`. + +01. Copy the DOT figure you want to translate (for instance, `trpl42-69.dot`) + from `/dot/` to `/FRENCH/dot/`. +02. Edit `/FRENCH/dot/trpl42-69.dot` and translate the text into French. + You should not translate the names and values of attributes. +03. Run `dot FRENCH/dot/trpl42-69.dot -Tsvg > FRENCH/src/img/trpl42-69.svg` +04. Edit the new file `FRENCH/src/img/trpl42-69.svg`: + - Within the `` tag, remove the `width` and `height` attributes, and + set the `viewBox` attribute to `0.00 0.00 1000.00 1000.00` or other values + that don't cut off the image. + - Replace every instance of `font-family="Times,serif"` with + `font-family="Times,Liberation Serif,serif"`. diff --git a/FRENCH/dot/trpl04-01.dot b/FRENCH/dot/trpl04-01.dot new file mode 100644 index 0000000000..ca90ee3e16 --- /dev/null +++ b/FRENCH/dot/trpl04-01.dot @@ -0,0 +1,26 @@ +digraph { + rankdir=LR; + overlap=false; + dpi=300.0; + node [shape="plaintext"]; + + table0[label=< + + + + + +
s1
nomvaleur
pointeur
taille5
capacité5
>]; + table1[label=< + + + + + + +
indicevaleur
0h
1e
2l
3l
4o
>]; + + edge[tailclip="false"]; + table0:pointer:c -> table1:pointee; +} + diff --git a/FRENCH/dot/trpl04-02.dot b/FRENCH/dot/trpl04-02.dot new file mode 100644 index 0000000000..2933b9b799 --- /dev/null +++ b/FRENCH/dot/trpl04-02.dot @@ -0,0 +1,35 @@ +digraph { + rankdir=LR; + overlap=false; + dpi=300.0; + node [shape="plaintext"]; + + table0[label=< + + + + + +
s1
nomvaleur
pointeur
taille5
capacité5
>]; + table3[label=< + + + + + +
s2
nomvaleur
pointeur
taille5
capacité5
>]; + + table1[label=< + + + + + + +
indicevaleur
0h
1e
2l
3l
4o
>]; + + edge[tailclip="false"]; + table0:pointer:c -> table1:pointee; + table3:pointer:c -> table1:pointee; +} + diff --git a/FRENCH/dot/trpl04-03.dot b/FRENCH/dot/trpl04-03.dot new file mode 100644 index 0000000000..48d9082e2f --- /dev/null +++ b/FRENCH/dot/trpl04-03.dot @@ -0,0 +1,44 @@ +digraph { + rankdir=LR; + overlap=false; + dpi=300.0; + node [shape="plaintext"]; + + table0[label=< + + + + + +
s2
nomvaleur
pointeur
taille5
capacité5
>]; + table1[label=< + + + + + + +
indicevaleur
0h
1e
2l
3l
4o
>]; + + table3[label=< + + + + + +
s1
nomvaleur
pointeur
taille5
capacité5
>]; + table4[label=< + + + + + + +
indicevaleur
0h
1e
2l
3l
4o
>]; + + + edge[tailclip="false"]; + table0:pointer:c -> table1:pointee; + table3:pointer:c -> table4:pointee; +} + diff --git a/FRENCH/dot/trpl04-04.dot b/FRENCH/dot/trpl04-04.dot new file mode 100644 index 0000000000..de16ad024c --- /dev/null +++ b/FRENCH/dot/trpl04-04.dot @@ -0,0 +1,35 @@ +digraph { + rankdir=LR; + overlap=false; + dpi=300.0; + node [shape="plaintext"]; + + table0[label=< + + + + + +
s1
nomvaleur
pointeur
taille5
capacité5
>]; + table3[label=< + + + + + +
s2
nomvaleur
pointeur
taille5
capacité5
>]; + + table1[label=< + + + + + + +
indicevaleur
0h
1e
2l
3l
4o
>]; + + edge[tailclip="false"]; + table0:pointer:c -> table1:pointee; + table3:pointer:c -> table1:pointee; +} + diff --git a/FRENCH/dot/trpl04-05.dot b/FRENCH/dot/trpl04-05.dot new file mode 100644 index 0000000000..f02f13f936 --- /dev/null +++ b/FRENCH/dot/trpl04-05.dot @@ -0,0 +1,32 @@ +digraph { + rankdir=LR; + overlap=false; + dpi=300.0; + node [shape="plaintext"]; + + table0[label=< + + + +
s
nomvaleur
pointeur
>]; + table1[label=< + + + + + +
s1
nomvaleur
pointeur
taille5
capacité5
>]; + table2[label=< + + + + + + +
indicevaleur
0h
1e
2l
3l
4o
>]; + + edge[tailclip="false"]; + table1:pointer:c -> table2:pointee; + table0:borrower:c -> table1:borrowee; +} + diff --git a/FRENCH/dot/trpl04-06.dot b/FRENCH/dot/trpl04-06.dot new file mode 100644 index 0000000000..cc5d7fb438 --- /dev/null +++ b/FRENCH/dot/trpl04-06.dot @@ -0,0 +1,41 @@ +digraph { + rankdir=LR; + overlap=false; + dpi=300.0; + node [shape="plaintext"]; + + table0[label=< + + + + +
world
nomvaleur
pointeur
taille5
>]; + + table3[label=< + + + + + +
s
nomvaleur
pointeur
taille11
capacité11
>]; + table4[label=< + + + + + + + + + + + + +
indicevaleur
0h
1e
2l
3l
4o
5
6w
7o
8r
9l
10d
>]; + + + edge[tailclip="false"]; + table0:pointer2:c -> table4:pointee2; + table3:pointer:c -> table4:pointee; +} + diff --git a/FRENCH/src/img/trpl04-01.svg b/FRENCH/src/img/trpl04-01.svg index c710fd89f9..c47e21dfc3 100644 --- a/FRENCH/src/img/trpl04-01.svg +++ b/FRENCH/src/img/trpl04-01.svg @@ -5,64 +5,64 @@ --> - + viewBox="0.00 0.00 1000.00 680.00" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"> + %3 - + table0 - -s1 - -nom - -valeur - -pointeur - - -taille - -5 - -capacité - -5 + +s1 + +nom + +valeur + +pointeur + + +taille + +5 + +capacité + +5 table1 - -indice - -valeur - -0 - -h - -1 - -e - -2 - -l - -3 - -l - -4 - -o + +indice + +valeur + +0 + +h + +1 + +e + +2 + +l + +3 + +l + +4 + +o table0:c->table1:pointee - - + + diff --git a/FRENCH/src/img/trpl04-02.svg b/FRENCH/src/img/trpl04-02.svg index 0ffc52c50e..f336171be4 100644 --- a/FRENCH/src/img/trpl04-02.svg +++ b/FRENCH/src/img/trpl04-02.svg @@ -5,91 +5,91 @@ --> - + viewBox="0.00 0.00 1000.00 1050.00" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"> + %3 - + table0 - -s1 - -nom - -valeur - -pointeur - - -taille - -5 - -capacité - -5 + +s1 + +nom + +valeur + +pointeur + + +taille + +5 + +capacité + +5 table1 - -indice - -valeur - -0 - -h - -1 - -e - -2 - -l - -3 - -l - -4 - -o + +indice + +valeur + +0 + +h + +1 + +e + +2 + +l + +3 + +l + +4 + +o table0:c->table1:pointee - - + + table3 - -s2 - -nom - -valeur - -pointeur - - -taille - -5 - -capacité - -5 + +s2 + +nom + +valeur + +pointeur + + +taille + +5 + +capacité + +5 table3:c->table1:pointee - - + + diff --git a/FRENCH/src/img/trpl04-03.svg b/FRENCH/src/img/trpl04-03.svg index 1d2d7327c8..29bea36bef 100644 --- a/FRENCH/src/img/trpl04-03.svg +++ b/FRENCH/src/img/trpl04-03.svg @@ -5,119 +5,119 @@ --> - + viewBox="0.00 0.00 1000.00 1310.00" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"> + %3 - + table0 - -s2 - -nom - -valeur - -pointeur - - -taille - -5 - -capacité - -5 + +s2 + +nom + +valeur + +pointeur + + +taille + +5 + +capacité + +5 table1 - -indice - -valeur - -0 - -h - -1 - -e - -2 - -l - -3 - -l - -4 - -o + +indice + +valeur + +0 + +h + +1 + +e + +2 + +l + +3 + +l + +4 + +o table0:c->table1:pointee - - + + table3 - -s1 - -nom - -valeur - -pointeur - - -taille - -5 - -capacité - -5 + +s1 + +nom + +valeur + +pointeur + + +taille + +5 + +capacité + +5 table4 - -indice - -valeur - -0 - -h - -1 - -e - -2 - -l - -3 - -l - -4 - -o + +indice + +valeur + +0 + +h + +1 + +e + +2 + +l + +3 + +l + +4 + +o table3:c->table4:pointee - - + + diff --git a/FRENCH/src/img/trpl04-04.svg b/FRENCH/src/img/trpl04-04.svg index a56ea03cc7..893f22404a 100644 --- a/FRENCH/src/img/trpl04-04.svg +++ b/FRENCH/src/img/trpl04-04.svg @@ -5,92 +5,92 @@ --> - + viewBox="0.00 0.00 1000.00 1050.00" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"> + %3 - + table0 - - -s1 - -nom - -valeur - -pointeur - - -taille - -5 - -capacité - -5 + + +s1 + +nom + +valeur + +pointeur + + +taille + +5 + +capacité + +5 table1 - -indice - -valeur - -0 - -h - -1 - -e - -2 - -l - -3 - -l - -4 - -o + +indice + +valeur + +0 + +h + +1 + +e + +2 + +l + +3 + +l + +4 + +o table0:c->table1:pointee - - + + table3 - -s2 - -nom - -valeur - -pointeur - - -taille - -5 - -capacité - -5 + +s2 + +nom + +valeur + +pointeur + + +taille + +5 + +capacité + +5 table3:c->table1:pointee - - + + diff --git a/FRENCH/src/img/trpl04-05.svg b/FRENCH/src/img/trpl04-05.svg new file mode 100644 index 0000000000..411c926f22 --- /dev/null +++ b/FRENCH/src/img/trpl04-05.svg @@ -0,0 +1,87 @@ + + + + + + +%3 + + + +table0 + +s + +nom + +valeur + +pointeur + + + + +table1 + +s1 + +nom + +valeur + +pointeur + + +taille + +5 + +capacité + +5 + + + +table0:c->table1:borrowee + + + + + +table2 + +indice + +valeur + +0 + +h + +1 + +e + +2 + +l + +3 + +l + +4 + +o + + + +table1:c->table2:pointee + + + + + diff --git a/FRENCH/src/img/trpl04-06.svg b/FRENCH/src/img/trpl04-06.svg new file mode 100644 index 0000000000..20ab84ea93 --- /dev/null +++ b/FRENCH/src/img/trpl04-06.svg @@ -0,0 +1,115 @@ + + + + + + +%3 + + + +table0 + +world + +nom + +valeur + +pointeur + + +taille + +5 + + + +table4 + +indice + +valeur + +0 + +h + +1 + +e + +2 + +l + +3 + +l + +4 + +o + +5 + + + +6 + +w + +7 + +o + +8 + +r + +9 + +l + +10 + +d + + + +table0:c->table4:pointee2 + + + + + +table3 + +s + +nom + +valeur + +pointeur + + +taille + +11 + +capacité + +11 + + + +table3:c->table4:pointee + + + + + diff --git a/FRENCH/src/img/trpl15-01.svg b/FRENCH/src/img/trpl15-01.svg new file mode 100644 index 0000000000..e5ae50baf4 --- /dev/null +++ b/FRENCH/src/img/trpl15-01.svg @@ -0,0 +1,43 @@ + + + + + + +%3 + + + +table0 + +Cons + +i32 + + +Cons + +i32 + + +Cons + +i32 + + +Cons + +i32 + + +Cons + +i32 + + + + + diff --git a/FRENCH/src/img/trpl15-02.svg b/FRENCH/src/img/trpl15-02.svg new file mode 100644 index 0000000000..c811d858cd --- /dev/null +++ b/FRENCH/src/img/trpl15-02.svg @@ -0,0 +1,26 @@ + + + + + + +%3 + + + +table0 + +Cons + +i32 + + +Box + +usize + + + diff --git a/FRENCH/src/img/trpl15-03.svg b/FRENCH/src/img/trpl15-03.svg new file mode 100644 index 0000000000..7d8b5b1ac9 --- /dev/null +++ b/FRENCH/src/img/trpl15-03.svg @@ -0,0 +1,109 @@ + + + + + + +%3 + + + +table4 +b + + + +table5 + +3 + +   + + + +table4:c->table5:pte4 + + + + + +table1 + +5 + +   + + + +table5:c->table1:pte0 + + + + + +table0 +a + + + +table0:c->table1:pte0 + + + + + +table2 + +10 + +   + + + +table1:c->table2:pte1 + + + + + +table3 + +Nil + + + +table2:c->table3:pte2 + + + + + +table6 +c + + + +table7 + +4 + +   + + + +table6:c->table7:pte6 + + + + + +table7:c->table1:pte0 + + + + + diff --git a/FRENCH/src/img/trpl15-04.svg b/FRENCH/src/img/trpl15-04.svg new file mode 100644 index 0000000000..4a39fc48c8 --- /dev/null +++ b/FRENCH/src/img/trpl15-04.svg @@ -0,0 +1,55 @@ + + + + + + +%3 + + +table0 + +a + + +table1 + +5 + + + + +table2 + +b + + +table3 + +10 + + + + +table0:ref->table1:data + + + + +table1:ref->table2:data + + + + +table2:ref->table3:data + + + + +table3:ref->table0:data + + + + + From 193fa2992163dbe6df4bca80c19c8f0fdc95ae0b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=ABl=20J=2E=20Pr=C3=A9sent?= <36854931+joeljpresent@users.noreply.github.com> Date: Mon, 11 Nov 2019 11:51:41 +0100 Subject: [PATCH 117/117] Proofread ch04-03 --- FRENCH/src/SUMMARY.md | 1 + FRENCH/src/ch04-03-slices.md | 279 +++++++++++++++-------------------- 2 files changed, 121 insertions(+), 159 deletions(-) diff --git a/FRENCH/src/SUMMARY.md b/FRENCH/src/SUMMARY.md index 4305682b80..95e39c60b0 100644 --- a/FRENCH/src/SUMMARY.md +++ b/FRENCH/src/SUMMARY.md @@ -24,6 +24,7 @@ - [Comprendre la possession](ch04-00-understanding-ownership.md) - [Qu'est-ce que la possession ?](ch04-01-what-is-ownership.md) - [Les références et l'emprunt](ch04-02-references-and-borrowing.md) + - [Le type slice](ch04-03-slices.md) - [Utiliser les structures pour structurer des données apparentées](ch05-00-structs.md) - [Définir et instancier des structures](ch05-01-defining-structs.md) diff --git a/FRENCH/src/ch04-03-slices.md b/FRENCH/src/ch04-03-slices.md index d8c9f6f1f2..3a93bfeaf2 100644 --- a/FRENCH/src/ch04-03-slices.md +++ b/FRENCH/src/ch04-03-slices.md @@ -2,7 +2,7 @@ ## The Slice Type --> -## Le type de découpage +## Le type slice -Un autre type de données qui ne prend pas possession est le *découpage*. Un -découpage vous permet d'obtenir une référence vers une suite continue d'éléments -d'une collection plutôt que toute la collection. +Un autre type de donnée qui ne prend pas possession est la *slice*. Une slice +vous permet d'obtenir une référence vers une séquence continue d'éléments d'une +collection plutôt que toute la collection. -Encart 4-7 : La fonction `premier_mot` qui retourne un -indice d'octet provenant du paramètre `String` +Encart 4-7 : La fonction `premier_mot` qui retourne +l'indice d'un octet provenant du paramètre `String` Comme nous avons besoin de parcourir la `String` élément par élément et de -vérifier si la valeur est un espace, nous allons convertir notre `String` en un +vérifier si la valeur est une espace, nous convertissons notre `String` en un tableau d'octets en utilisant la méthode `as_bytes` : -Comme la méthode `enumerate` retourne un tuple, ne pouvons utiliser des motifs +Comme la méthode `enumerate` retourne un tuple, nous pouvons utiliser des motifs pour déstructurer ce tuple, comme nous pourrions le faire n'importe où avec Rust. Donc dans la boucle `for`, nous précisons un motif qui indique que nous -définissons `i` pour l'indice à partir du tuple et `&element` pour l'octet dans +définissons `i` pour l'indice au sein du tuple et `&element` pour l'octet dans le tuple. Comme nous obtenons une référence vers l'élément avec `.iter().enumerate()`, nous utilisons `&` dans le motif. @@ -174,8 +173,8 @@ using the byte literal syntax. If we find a space, we return the position. Otherwise, we return the length of the string by using `s.len()`: --> -Avec la boucle `for`, nous recherchons l'octet qui représente l'espace en -utilisant la syntaxe des mots binaires. Si nous trouvons un espace, nous +Au sein de la boucle `for`, nous recherchons l'octet qui représente l'espace en +utilisant la syntaxe de littéral d'octet. Si nous trouvons une espace, nous retournons sa position. Sinon, nous retournons la taille de la chaîne en utilisant `s.len()` : @@ -191,7 +190,7 @@ s.len() --> ```rust,ignore - if item == b' ' { + if element == b' ' { return i; } } @@ -289,12 +288,12 @@ the variable `s` to try to extract the first word out, but this would be a bug because the contents of `s` have changed since we saved `5` in `word`. --> -Ce programme se compile sans aucune erreur et le serait toujours si nous +Ce programme se compile sans aucune erreur et le ferait toujours si nous utilisions `mot` après avoir appelé `s.clear()`. Comme `mot` n'est pas du tout -lié à `s`, `mot` contient toujours la valeur `5`. Nous pourrions -utiliser cette valeur `5` avec la variable `s` pour essayer d'en extraire le -premier mot, mais cela serait un bogue, car le contenu de `s` a changé depuis -que nous avons enregistré `5` dans `mot`. +lié à `s`, `mot` contient toujours la valeur `5`. Nous pourrions utiliser cette +valeur `5` avec la variable `s` pour essayer d'en extraire le premier mot, mais +cela serait un bogue, car le contenu de `s` a changé depuis que nous avons +enregistré `5` dans `mot`. -Maintenant nous avons un indice de début *et* un indice de fin, donc nous avons -encore plus de valeurs qui sont calculées à partir de la donnée à un instant -donné, mais qui n'est pas en temps réel. Nous avons maintenant trois variables -isolées qui ont besoin d'être maintenues à jour. +Maintenant, nous avons un indice de début *et* un indice de fin, donc nous avons +encore plus de valeurs qui sont calculées à partir d'une donnée dans un état +donné, mais qui ne sont pas liées du tout à l'état de cette donnée. Nous avons +maintenant trois variables isolées qui ont besoin d'être maintenues à jour. -Heureusement, Rust a une solution pour ce problème : les découpages de chaînes -de caractères. +Heureusement, Rust a une solution pour ce problème : les *slices* de chaînes de +caractères. -### Les découpages de chaînes de caractères +### Les slices de chaînes de caractères -Un *découpage de chaîne de caractère* est une référence à une partie -d'une `String`, et ressemble à ceci : - - +Une *slice de chaîne de caractères* (ou *slice de chaîne*) est une référence à +une partie d'une `String`, et ressemble à ceci : ```rust let s = String::from("hello world"); @@ -385,14 +375,14 @@ the length of the slice, which corresponds to `ending_index` minus a slice that contains a pointer to the 7th byte of `s` with a length value of 5. --> -Nous pouvons créer des découpages en utilisant un intervalle entre crochets en -spécifiant `[indice_debut..indice_fin]`, où `indice_debut` est la première -position dans le découpage et `indice_fin` est la dernière position dans le -découpage plus une position. En interne, la structure de données du découpage -enregistre la position de départ et la longueur du découpage, ce qui correspond -à `indice_fin` moins `indice_debut`. Donc dans le cas du -`let world = &s[6..11];`, `world` va être un découpage qui a un pointeur vers le -7e octet de `s` et une longueur de 5. +Nous pouvons créer des slices en utilisant un intervalle entre crochets en +spécifiant `[indice_debut..indice_fin]`, où `indice_debut` est la position du +premier octet de la slice et `indice_fin` est la position juste après le dernier +octet de la slice. En interne, la structure de données de la slice stocke la +position de départ et la longueur de la slice, ce qui correspond à `indice_fin` +moins `indice_debut`. Donc dans le cas de `let world = &s[6..11];`, `world` est +une slice qui contient un pointeur vers l'octet d'indice 6 de `s` et une +longueur de 5. + -world contient un pointeur vers le 6ième octet de la String s et une longueur de 5 +world contient un pointeur vers l'octet d'indice 6 de la String s et
+une longueur de 5 -Illustration 4-6 : Un découpage d'une chaîne qui pointe -vers une partie d'une `String` +Illustration 4-6 : Une slice de chaîne qui pointe vers +une partie d'une `String` - -```rust -let s = String::from("hello"); - -let decoupage = &s[0..2]; -let decoupage = &s[..2]; -``` -De la même manière, si votre découpage contient les derniers octets de la -`String`, vous pouvez ne rien mettre à la fin. Cela veut dire que ces deux -ceci revient au même : +De la même manière, si votre slice contient le dernier octet de la `String`, +vous pouvez ne rien mettre à la fin. Cela veut dire que ces deux cas sont +identiques : -Vous pouvez aussi ne mettre aucune limite pour créer un découpage de toute la +Vous pouvez aussi ne mettre aucune limite pour créer une slice de toute la chaîne de caractères. Ces deux cas sont donc identiques : -> Remarque : Les indices de l'intervalle d'un découpage d'une chaîne de -> caractères doivent toujours se trouver dans les zones acceptables de -> séparation des caractères encodés en UTF-8. Si vous essayez de créer un -> découpage d'une chaîne de caractères qui s'arrête au milieu d'un caractère -> encodé sur plusieurs octets, votre programme va se fermer avec une erreur. -> Afin de simplifier l'explication des découpages de chaînes de caractères, nous -> utiliserons uniquement l'ASCII dans cette section; nous verons la gestion de -> l'UTF-8 dans une section du [chapitre 8][strings]. +> Remarque : Les indices de l'intervalle d'une slice de chaîne doivent toujours +> se trouver dans les zones acceptables de séparation des caractères encodés en +> UTF-8. Si vous essayez de créer une slice de chaîne qui s'arrête au milieu +> d'un caractère encodé sur plusieurs octets, votre programme va se fermer avec +> une erreur. Afin de simplifier l'explication des slices de chaînes, nous +> utiliserons uniquement l'ASCII dans cette section ; nous verrons la gestion +> d'UTF-8 dans la section [“Stocker du texte encodé en UTF-8 avec les chaînes de +> caractères”][strings] du chapitre 8. -Maintenant que nous savons tout cela, essayons de ré-écrire `premier_mot` pour -retourner un découpage. Le type pour les “découpages de chaînes de caractères” +Maintenant que nous savons tout cela, essayons de réécrire `premier_mot` pour +qu'il retourne une slice. Le type pour les slices de chaînes de caractères s'écrit `&str` : Nous récupérons l'indice de la fin du mot de la même façon que nous l'avions -fait dans l'encart 4-7, en cherchant la première occurrence d'un espace. Lorsque -nous trouvons un espace, nous retournons un découpage de la chaîne de caractère -en utilisant le début de la chaîne de caractères et l'indice de l'espace comme -indices de début et fin. +fait dans l'encart 4-7, en cherchant la première occurrence d'une espace. +Lorsque nous trouvons une espace, nous retournons une slice de chaîne en +utilisant le début de la chaîne de caractères et l'indice de l'espace comme +indices de début et de fin respectivement. -Désormais quand nous appelons `premier_mot`, nous récupérons une seule valeur -qui est liée à la donnée de base. La valeur est construite avec une référence -vers le point de départ du découpage et avec le nombre d'éléments dans le -découpage. +Désormais, quand nous appelons `premier_mot`, nous récupérons une unique valeur +qui est liée à la donnée de base. La valeur se compose d'une référence vers le +point de départ de la slice et du nombre d'éléments dans la slice. -Retourner un découpage fonctionnerait aussi pour une fonction `second_mot` : +Retourner une slice fonctionnerait aussi pour une fonction `second_mot` : -Nous avons maintenant une API simple qui est bien plus difficile à perturber, +Nous avons maintenant une API simple qui est bien plus difficile à mal utiliser, puisque le compilateur va s'assurer que les références dans la `String` seront -toujours en vigueur. Souvenez-vous du bogue du programme de l'encart 4-8, +toujours en vigueur. Vous souvenez-vous du bogue du programme de l'encart 4-8, lorsque nous avions un indice vers la fin du premier mot mais qu'ensuite nous -avions vidé la chaîne de caractères et que notre index n'était plus valide ? Ce +avions vidé la chaîne de caractères et que notre indice n'était plus valide ? Ce code était logiquement incorrect, mais ne montrait pas immédiatement une erreur. Les problèmes apparaîtront plus tard si nous essayons d'utiliser l'indice du -premier mot avec une chaîne de caractère qui a été vidée. Les découpages rendent -ce bogue impossible et nous signale bien plus tôt que nous avons un problème -avec notre code. Utiliser la version avec le découpage de `premier_mot` va -afficher une erreur au moment de la compilation : +premier mot avec une chaîne de caractères qui a été vidée. Les slices rendent ce +bogue impossible et nous signalent bien plus tôt que nous avons un problème avec +notre code. Utiliser la version avec la slice de `premier_mot` va causer une +erreur de compilation : -Rappellons-nous que d'après les règles d'emprunt, si nous avons une référence +Rappelons-nous que d'après les règles d'emprunt, si nous avons une référence immuable vers quelque chose, nous ne pouvons pas avoir une référence mutable -en même temps. Etant donné que `clear` a besoin de modifier la `String`, il a +en même temps. Étant donné que `clear` a besoin de modifier la `String`, il a besoin d'une référence mutable. Rust interdit cette situation, et la compilation échoue. Non seulement Rust a simplifié l'utilisation de notre API, mais il a aussi éliminé une catégorie entière d'erreurs au moment de la compilation ! @@ -710,22 +693,16 @@ aussi éliminé une catégorie entière d'erreurs au moment de la compilation ! #### String Literals Are Slices --> -#### Les chaînes de caractères pures sont des découpages +#### Les littéraux de chaîne de caractères sont aussi des slices -Rappellez-vous lorsque nous avons appris que les chaînes de caractères pures -étaient enregistrées dans le binaire. Maintenant que nous connaissons les -découpages, nous pouvons désormais comprendre les chaînes de caractères pures. - - +Rappelez-vous lorsque nous avons appris que les littéraux de chaîne de +caractères étaient enregistrés dans le binaire. Maintenant que nous connaissons +les slices, nous pouvons désormais comprendre les littéraux de chaîne. ```rust let s = "Hello, world!"; @@ -737,24 +714,23 @@ the binary. This is also why string literals are immutable; `&str` is an immutable reference. --> -Ici, le type de `s` est un `&str` : c'est un découpage qui pointe vers un -endroit précis du binaire. C'est aussi la raison pour laquelle les chaînes de -caractères pures sont immuables; `&str` est une référence immuable. +Ici, le type de `s` est un `&str` : c'est une slice qui pointe vers un endroit +précis du binaire. C'est aussi la raison pour laquelle les littéraux de chaîne +sont immuables ; `&str` est une référence immuable. -#### Les découpages de chaînes de caractères en paramètres +#### Les slices de chaînes de caractères en paramètres -Savoir que vous pouvez utiliser des découpages de chaînes de caractères pures et -des `String` nous invite à apporter une petite amélioration sur `premier_mot`, -dont voici sa signature : +Savoir que l'on peut utiliser des slices de littéraux et de `String` nous incite +à apporter une petite amélioration à `premier_mot`, dont voici la signature : -Un Rustacé plus expérimenté écrirait plutôt la signature de l'encart 4_9, car +Un Rustacé plus expérimenté écrirait plutôt la signature de l'encart 4-9, car cela nous permet d'utiliser la même fonction sur les `&String` et aussi les `&str` : @@ -792,7 +768,7 @@ a string slice for the type of the `s` parameter
--> Encart 4-9 : Amélioration de la fonction `premier_mot` en -utilisant un découpage de chaîne de caractère comme type du paramètre `s` +utilisant une slice de chaîne de caractères comme type du paramètre `s`
-Si nous avons un découpage de chaîne de caractères, nous pouvons lui donner -directement. Si nous avons une `String`, nous pouvons envoyer un découpage de -toute la `String`. Concevoir une fonction afin de prendre un découpage de chaîne -de caractères plutôt qu'une référence à une `String` rend notre API plus -générique et plus utile sans perdre aucune fonctionnalité : +Si nous avons une slice de chaîne, nous pouvons la passer en argument +directement. Si nous avons une `String`, nous pouvons envoyer une slice de toute +la `String`. Définir une fonction qui prend une slice de chaîne plutôt qu'une +référence à une `String` rend notre API plus générique et plus utile sans perdre +aucune fonctionnalité : -### Les autres découpages +### Les autres slices -Les découpages de chaînes de caractères, comme vous pouvez l'imaginer, sont -spécifiques aux chaînes de caractères. Mais il existe aussi un type plus -générique. Imaginons ce tableau de données : - - +Les slices de chaînes de caractères, comme vous pouvez l'imaginer, sont +spécifiques aux chaînes de caractères. Mais il existe aussi un type de slice +plus générique. Imaginons ce tableau de données : ```rust let a = [1, 2, 3, 4, 5]; @@ -904,23 +873,15 @@ Just as we might want to refer to a part of a string, we might want to refer to part of an array. We’d do so like this: --> -Comme nous pouvons nous référer à un échantillon d'une chaîne de caractères, +Tout comme nous pouvons nous référer à une partie d'une chaîne de caractères, nous pouvons nous référer à une partie d'un tableau. Nous pouvons le faire comme ceci : - - -```rust -let a = [1, 2, 3, 4, 5]; - -let decoupage = &a[1..3]; -``` -Ce découpage est de type `&[i32]`. Il fonctionne de la même manière que les -découpages de chaînes de caractères, en enregistrant une référence vers le -premier élément et une longueur. Vous réutiliserez ce type de découpage pour -toutes les autres types de collections. Nous aborderons ces collections en -détail quand lorsque nous verrons les vecteurs au chapitre 8. +Cette slice est de type `&[i32]`. Elle fonctionne de la même manière que les +slices de chaînes de caractères, en enregistrant une référence vers le premier +élément et une longueur. Vous utiliserez ce type de slice pour tous les autres +types de collections. Nous aborderons ces collections en détail quand nous +verrons les vecteurs au chapitre 8. -Les concepts de possession, d'emprunt, et les découpages garantissent la -sécurité de la mémoire dans les programmes Rust au moment de la compilation. Le -langage Rust vous donne le contrôle sur l'utilisation de la mémoire comme tous -les autres systèmes de langages de programmation, mais celui qui possède les -données nettoie automatiquement ces données quand il sort de la portée, et cela -vous permet de ne pas avoir à écrire et déboguer du code en plus pour avoir -cette fonctionnalité. +Les concepts de possession, d'emprunt et de slices garantissent la sécurité de +la mémoire dans les programmes Rust au moment de la compilation. Le langage Rust +vous donne le contrôle sur l'utilisation de la mémoire comme tous les autres +langages de programmation système, mais le fait que celui qui possède des +données nettoie automatiquement ces données quand il sort de la portée vous +permet de ne pas avoir à écrire et déboguer du code en plus pour avoir cette +fonctionnalité.