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/SUMMARY.md b/FRENCH/src/SUMMARY.md index 64539c7391..4305682b80 100644 --- a/FRENCH/src/SUMMARY.md +++ b/FRENCH/src/SUMMARY.md @@ -23,6 +23,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) - [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/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..5edcfd5c8f 100644 --- a/FRENCH/src/ch01-01-installation.md +++ b/FRENCH/src/ch01-01-installation.md @@ -176,12 +176,16 @@ pour Visual Studio 2013 ou plus récent. La méthode la plus facile pour obtenir les outils de compilation est d'installer [Build Tools pour Visual Studio 2019][visualstudio]. -[install]: https://www.rust-lang.org/tools/install + + + +[install]: https://www.rust-lang.org/tools/install [visualstudio]: https://www.visualstudio.com/fr/downloads/#build-tools-for-visual-studio-2019 + ```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..4729b05608 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. *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 27ddb48c3d..f01ddc9883 100644 --- a/FRENCH/src/ch03-03-how-functions-work.md +++ b/FRENCH/src/ch03-03-how-functions-work.md @@ -379,9 +379,11 @@ fn main() { } ``` + + Encart 3-1 : une fonction `main` qui contient une instruction 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 +1076,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… @@ -1277,12 +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 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..8f9a7572f4 --- /dev/null +++ b/FRENCH/src/ch04-02-references-and-borrowing.md @@ -0,0 +1,854 @@ + + +## Les références et l'emprunt + + + +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_taille`, car la +`String` a été déplacée dans `calculer_taille`. + + + +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 : + + + +Fichier : src/main.rs + + + +```rust +fn main() { + let s1 = String::from("hello"); + + let long = calculer_taille(&s1); + + println!("La taille de '{}' est {}.", s1, long); +} + +fn calculer_taille(s: &String) -> usize { + s.len() +} +``` + + + +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` à `calculer_taille`, 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 en prendre possession. L'illustration 4-5 nous montre cela dans +un schéma. + + + + + +&String s qui pointe vers la String s1 + + + +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 +> *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 l'appel à la fonction : + + + +```rust +# fn calculer_taille(s: &String) -> usize { +# s.len() +# } +let s1 = String::from("hello"); + +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 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. + + + +De la même manière, la signature de la fonction utilise `&` pour indiquer que +le type du paramètre `s` est une référence. Ajoutons quelques commentaires +explicatifs : + + + +```rust +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 de ce + // à 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 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 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. + + + +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 le lui emprunter. Et quand vous avez fini, vous devez +le lui rendre. + + + +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 ! + + + +Fichier : src/main.rs + + + +```rust,ignore,does_not_compile +fn main() { + let s = String::from("hello"); + + changer(&s); +} + +fn changer(texte: &String) { + texte.push_str(", world"); +} +``` + + + +Entrée 4-6 : Tentative de modification d'une valeur +empruntée. + + + +Voici l'erreur : + + + +```text +error[E0596]: cannot borrow immutable borrowed content `*texte` as mutable + --> error.rs:8:5 + | +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. + + + +### Les références mutables + + + +Nous pouvons résoudre l'erreur du code de l'encart 4-6 avec une petite +modification : + + + +Fichier : src/main.rs + + + +```rust +fn main() { + let mut s = String::from("hello"); + + changer(&mut s); +} + +fn changer(texte: &mut String) { + texte.push_str(", world"); +} +``` + + + +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`. + + + +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 : + + + +Fichier : src/main.rs + + + +```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 : + +```text +error[E0499]: cannot borrow `s` as mutable more than once at a time + -- > src/main.rs:5:14 + | +4 | let r1 = &mut s; + | ------ first mutable borrow occurs here +5 | let r2 = &mut s; + | ^^^^^^ second mutable borrow occurs here +6 | +7 | println!("{}, {}", r1, r2); + | -- first borrow later used here +``` + + + +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. + + + +L'avantage d'avoir cette contrainte est que Rust peut empêcher les accès +concurrents au moment de la compilation. Un *accès concurrent* est une situation +de concurrence qui se produit lorsque ces trois facteurs se combinent : + + + +* 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 mécanisme pour synchroniser l'accès aux données. + + + +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 +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 même temps* : + + + +```rust +let mut s = String::from("hello"); + +{ + let r1 = &mut s; + +} // r1 sort de la portée ici, donc nous pouvons créer une nouvelle référence + // sans problèmes. + +let r2 = &mut s; +``` + + + +Une règle similaire existe pour combiner les références immuables et mutables. +Ce code va mener à une erreur : + + + +```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 : + + + +```text +error[E0502]: cannot borrow `s` as mutable because it is also borrowed as immutable + -- > src/main.rs:6:14 + | +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 mutable pendant que +nous en avons une autre immuable. Les utilisateurs d'une référence immuable ne +s'attendent pas à ce que sa valeur change soudainement ! Cependant, +l'utilisation de plusieurs références immuables ne pose pas de problème, car +simplement lire une donnée ne va pas affecter la lecture de la donnée par les +autres. + + + +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 : + + + + + +```rust,edition2018,ignore +let mut s = String::from("hello"); + +let r1 = &s; // sans problème +let r2 = &s; // sans problème +println!("{} et {}", r1, r2); +// r1 et r2 ne sont plus utilisés à partir d'ici + +let r3 = &mut s; // sans problème +println!("{}", r3); +``` + + + +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, 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é. + + + +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 pendouillantes + + + +Avec les langages qui utilisent les pointeurs, il est facile de créer par erreur +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. + + + +Essayons de créer une référence pendouillante, ce que Rust va empêcher avec une +erreur au moment de la compilation : + + + +Fichier : src/main.rs + + + +```rust,ignore,does_not_compile +fn main() { + let reference_vers_rien = pendouille(); +} + +fn pendouille() -> &String { + let s = String::from("hello"); + + &s +} +``` + + + +Voici l'erreur : + + + +```text +error[E0106]: missing lifetime specifier + --> main.rs:5:16 + | +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 + = help: consider giving it a 'static lifetime +``` + + + +Ce message d'erreur fait référence à une fonctionnalité que nous n'avons pas +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 : + + + +```text +this function's return type contains a borrowed value, but there is no value +for it to be borrowed from. +``` + +Ce qui peut se traduire par : + +```text +Le type de retour de cette fonction contient une valeur empruntée, mais il n'y a +plus aucune valeur qui peut être empruntée. +``` + + + +Regardons de plus près ce qui se passe exactement à chaque étape de notre code +de `pendouille` : + + + +Fichier : src/main.rs + + + +```rust,ignore,does_not_compile +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 disparaît. + // Attention, danger ! +``` + + + +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. + + + +Ici la solution est de renvoyer la `String` directement : + + + +```rust +fn ne_pendouille_pas() -> String { + let s = String::from("hello"); + + s +} +``` + + + +Cela fonctionne sans problème. La possession est transférée à la valeur de +retour de la fonction, et rien n'est désalloué. + + + +### Les règles de référencement + + + +Récapitulons ce que nous avons vu à propos des références : + + + +* À 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. + + + +Ensuite, nous aborderons un autre type de référence : les *slices*. 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 index e64415fe43..20ab84ea93 100644 --- a/FRENCH/src/img/trpl04-06.svg +++ b/FRENCH/src/img/trpl04-06.svg @@ -5,111 +5,111 @@ --> - + viewBox="0.00 0.00 1000.00 1200.00" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"> + %3 - + table0 - -world - -name - -value - -ptr - - -len - -5 + +world + +nom + +valeur + +pointeur + + +taille + +5 table4 - -index - -value - -0 - -h - -1 - -e - -2 - -l - -3 - -l - -4 - -o - -5 - - - -6 - -w - -7 - -o - -8 - -r - -9 - -l - -10 - -d + +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 - -name - -value - -ptr - - -len - -11 - -capacity - -11 + +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 + + + + + diff --git a/FRENCH/src/translation-terms.md b/FRENCH/src/translation-terms.md index 07d9b68d74..c4fa27b614 100644 --- a/FRENCH/src/translation-terms.md +++ b/FRENCH/src/translation-terms.md @@ -47,11 +47,15 @@ français. | crash | plantage | - | | crate | crate | nom féminin (une *crate*) | | curly bracket | accolade | - | +| dangling | pendouillant | - | +| data race | accès concurrent | - | | data representation | modèle de données | - | +| deallocate | désalloué | - | | debug | déboguer | - | | debugging | débogage | - | | deep copy | copie en profondeur | - | | dependency | dépendance | - | +| dereferencing | déréférencement | - | | destructure | déstructurer | - | | DevOps | DevOps | - | | dot notation | la notation avec un point | - | @@ -135,6 +139,7 @@ français. | prelude | étape préliminaire | - | | procedural macro | macro procédurale | - | | project chapter | chapitre de projet | - | +| race condition | situation de concurrence | - | | pushing onto the stack | empiler | - | | raw identifier | identificateur brut | - | | README | README | - |