Galerie de cartes mentales Maîtriser RUST 2e édition
Il s'agit d'une carte mentale sur la maîtrise de RUST. Grâce aux étapes et suggestions ci-dessus, vous pouvez progressivement améliorer vos compétences en programmation Rust et profiter de la sécurité de la mémoire et des performances efficaces apportées par Rust.
Modifié à 2024-04-04 15:14:48Cent ans de solitude est le chef-d'œuvre de Gabriel Garcia Marquez. La lecture de ce livre commence par l'analyse des relations entre les personnages, qui se concentre sur la famille Buendía et raconte l'histoire de la prospérité et du déclin de la famille, de ses relations internes et de ses luttes politiques, de son métissage et de sa renaissance au cours d'une centaine d'années.
Cent ans de solitude est le chef-d'œuvre de Gabriel Garcia Marquez. La lecture de ce livre commence par l'analyse des relations entre les personnages, qui se concentre sur la famille Buendía et raconte l'histoire de la prospérité et du déclin de la famille, de ses relations internes et de ses luttes politiques, de son métissage et de sa renaissance au cours d'une centaine d'années.
La gestion de projet est le processus qui consiste à appliquer des connaissances, des compétences, des outils et des méthodologies spécialisés aux activités du projet afin que celui-ci puisse atteindre ou dépasser les exigences et les attentes fixées dans le cadre de ressources limitées. Ce diagramme fournit une vue d'ensemble des 8 composantes du processus de gestion de projet et peut être utilisé comme modèle générique.
Cent ans de solitude est le chef-d'œuvre de Gabriel Garcia Marquez. La lecture de ce livre commence par l'analyse des relations entre les personnages, qui se concentre sur la famille Buendía et raconte l'histoire de la prospérité et du déclin de la famille, de ses relations internes et de ses luttes politiques, de son métissage et de sa renaissance au cours d'une centaine d'années.
Cent ans de solitude est le chef-d'œuvre de Gabriel Garcia Marquez. La lecture de ce livre commence par l'analyse des relations entre les personnages, qui se concentre sur la famille Buendía et raconte l'histoire de la prospérité et du déclin de la famille, de ses relations internes et de ses luttes politiques, de son métissage et de sa renaissance au cours d'une centaine d'années.
La gestion de projet est le processus qui consiste à appliquer des connaissances, des compétences, des outils et des méthodologies spécialisés aux activités du projet afin que celui-ci puisse atteindre ou dépasser les exigences et les attentes fixées dans le cadre de ressources limitées. Ce diagramme fournit une vue d'ensemble des 8 composantes du processus de gestion de projet et peut être utilisé comme modèle générique.
Maîtrise de RUST
Chapitre 1 Premiers pas avec Rust
1.1 Qu'est-ce que Rust et pourquoi vous en avez besoin
Rust est un langage de programmation rapide, hautement simultané, sûr et puissant, créé et publié à l'origine en 2006 par Graydon Hoare. Il s'agit désormais d'un langage open source, principalement maintenu et développé par l'équipe Mozilla et de nombreux membres de la communauté open source.
Rust dispose d'un site Web de développement open source sur GitHub et sa dynamique de développement est très rapide. De nouvelles fonctionnalités sont ajoutées au langage via un processus de demande de commentaires (RFC) piloté par la communauté, dans lequel n'importe qui peut soumettre de nouvelles fonctionnalités, puis les décrire en détail dans un document RFC. Un consensus est ensuite recherché sur la RFC, et si un consensus est atteint, la fonctionnalité entre dans la phase de mise en œuvre.
Rust existe en tant que langage statiquement et fortement typé. Les propriétés statiques signifient que le compilateur dispose d'informations sur toutes les variables et types pertinents au moment de la compilation et effectue de nombreuses vérifications au moment de la compilation, ne laissant qu'une petite quantité de vérification de type au moment de l'exécution.
1.2 Installer la chaîne d'outils Rust
rustup.rs
1.3 Introduction à la rouille
1.3.1 Types primitifs
bouffon
Ce sont des valeurs booléennes courantes qui peuvent être vraies ou fausses.
carboniser
personnage
entier
Ce type est caractérisé par la largeur de bits. La longueur maximale prise en charge par Rust est de 128 bits.
taille
Un entier signé de taille variable (la taille dépend de la taille du pointeur sous-jacent).
utiliser
Entier non signé de taille variable (la taille dépend de la taille du pointeur sous-jacent).
f32
type à virgule flottante f32 bits
f64
Type à virgule flottante f64 bits
[T;N]
Un tableau de taille fixe, T représente le type d'élément, N représente le nombre d'éléments et est une constante non négative au moment de la compilation.
[T]
Une vue dimensionnée dynamiquement d’une séquence contiguë, T représentant n’importe quel type.
str
Découpage de chaînes, principalement utilisé comme référence, c'est-à-dire &str
(T, U, ..)
Les séquences finies, T et U peuvent être de types différents.
fn(i32)->i32
Une fonction qui reçoit un paramètre de type i32 et renvoie un paramètre de type i32. Les fonctions ont également un type.
1.3.2 Déclaration de variable et immuabilité
Dans Rust, nous utilisons le mot-clé let pour déclarer des variables. Une fois qu’une variable est initialisée, aucune autre valeur ne peut lui être attribuée. Si vous devez ultérieurement faire pointer la variable vers une autre variable (du même type), vous devez la faire précéder du mot-clé mut.
1.3.3 Fonction
Les fonctions résument un ensemble d'instructions en entités nommées qui peuvent ensuite être appelées à partir d'un autre code et aident les utilisateurs à gérer la complexité.
fn ajouter (a : u64, b : u64) -> u64 { un B } fn main() { soit a : u64 = 17 ; soit b = 3; soit result = add(a, b); println!("Résultat {}", résultat); }
Les fonctions sont essentiellement des expressions qui renvoient une valeur, qui par défaut est une valeur de type () (unité), similaire au type de retour void en C/C++.
1.3.4 Clôture
Rust prend en charge les fermetures. Les fermetures sont similaires aux fonctions mais contiennent plus d'informations sur l'environnement ou la portée dans laquelle elles sont déclarées. Bien que les fonctions soient associées à un nom, les définitions des fermetures n'en ont pas, mais elles peuvent être affectées à des variables. Un autre avantage de l'inférence de type Rust est que dans la plupart des cas, vous pouvez spécifier des paramètres pour les fermetures sans types. Il s'agit de la fermeture la plus simple "let my_closure = ||();". Nous définissons une fermeture sans paramètre qui ne fait rien. On peut alors l'appeler via my_closure(), qui s'apparente à une fonction. Les deux barres verticales "||" sont utilisées pour stocker les paramètres de fermeture, tels que |a, b|. Parfois, il est nécessaire de spécifier le type de paramètre (|a:u32|) lorsque Rust ne parvient pas à déterminer le type correct.
fn main() { soit doubler = |x| x * 2; soit valeur = 5 ; soit deux fois = doubler (valeur); println!("{} doublé est {}", valeur, deux fois); laissez big_closure = |b, c| soit z = bc; z * deux fois } ; let some_number = big_closure(1, 2); println!("Résultat de la fermeture : {}", some_number); }
1.3.5 Chaîne
La chaîne est l’un des types de données les plus couramment utilisés dans n’importe quel langage de programmation. Dans Rust, ils apparaissent généralement sous deux formes : le type &str et le type String. Les chaînes Rust sont garanties comme étant des séquences d’octets codées en UTF-8 valides. Elles ne se terminent pas par NULL comme les chaînes C et peuvent contenir des octets nuls entre les chaînes.
fn main() { let question = "Comment vas-tu ?"; let person: String = "Bob".to_string(); let namaste = String::from("zd"); println!("{}! {} {}", namaste, question, personne); }
Dans le code ci-dessus, le type de personne et le nom sont String et le type de question est &str. Il existe de nombreuses façons de créer des données de type String. Les données de type chaîne sont allouées sur le tas. Les données de type &str sont généralement un pointeur vers une chaîne existante. Ces chaînes se trouvent sur la pile et le tas, ou elles peuvent être des chaînes dans le segment de données du code objet compilé.
1.3.6 Conditions et jugements
Les jugements conditionnels dans Rust sont similaires à ceux des autres langages. Ils suivent également une structure if else de type C.
fn main() { laissez rust_is_awesome = true ; si rust_is_awesome { println!("En effet"); } autre { println!("Eh bien, tu devrais essayer Rust!"); } }
Dans Rust, la construction if n'est pas une instruction, mais une expression. Dans le langage général de la programmation, les instructions ne renvoient aucune valeur, contrairement aux expressions. Cette distinction signifie que les conditions if else dans Rust renvoient toujours une valeur. La valeur peut être de type vide () ou une valeur réelle. Quelle que soit la dernière ligne d'accolades, elle devient la valeur de retour de l'expression if else. Il est important de noter que les branches if et else doivent avoir le même type de retour.
fn main() { soit résultat = si 1 == 2 { "Attends quoi?" } autre { "La rouille a du sens" } ; println!("Tu sais quoi ? {}.", résultat); }
Lorsque la valeur à attribuer est renvoyée par l'expression if else, nous devons utiliser un point-virgule comme marque de fin. Par exemple, if est une expression, alors let est une instruction qui s'attend à ce que nous ayons un point-virgule à la fin.
1.3.7 expression de correspondance
Les expressions de correspondance de Rust sont très simples et faciles à utiliser. Il est fondamentalement similaire à une version simplifiée de l'instruction switch en langage C, permettant aux utilisateurs de porter des jugements en fonction de la valeur de la variable et de l'existence ou non d'une fonctionnalité de filtrage avancée.
fn req_status() -> u32 { 200 } fn main() { let status = req_status(); statut du match { 200 => println!("Succès"), 404 => println!("Introuvable"), autre => { println!("La demande a échoué avec le code : {}", autre); } } }
Chaque correspondance doit renvoyer le même type. De plus, nous devons effectuer une correspondance exacte sur toutes les valeurs correspondantes possibles. Rust nous permet d'ignorer les possibilités restantes en utilisant catch all variables (ici autres) ou _ (trait de soulignement).
1.3.8 Boucle
Faire quelque chose de manière répétée dans Rust peut être accompli en utilisant 3 constructions, à savoir loop, while et for. Dans toutes ces constructions, les mots-clés continue et break sont généralement inclus, vous permettant respectivement de sauter et de sortir de la boucle.
fn main() { soit mut x = 1024 ; boucle { si x < 0 { casser; } println!("{} encore des courses à faire", x); x-= 1 ; } }
Une fonctionnalité supplémentaire de l'exécution de boucles dans Rust est la possibilité d'étiqueter les blocs de code de boucle avec des noms. Cela peut être utilisé dans les situations où vous avez deux boucles imbriquées ou plus et que vous souhaitez rompre avec l'une d'entre elles, pas seulement pour les boucles qui contiennent directement des instructions break.
fn silly_sub(a : i32, b : i32) -> i32 { soit mut résultat = 0 ; 'incrément : boucle { si résultat == a { soit mut déc = b; 'décrémenter : boucle { ifdec==0{ casser 'incrément; } autre { résultat -= 1 ; décembre -= 1 ; } } } autre { résultat = 1 ; } } résultat } fn main() { soit a = 10 ; soit b = 4; soit result = silly_sub(a, b); println!("{} moins {} est {}", a, b, résultat); }
Rust a également le mot-clé for, qui est similaire à la boucle for utilisée dans d'autres langages, mais leur implémentation est complètement différente. La boucle for de Rust est essentiellement du sucre syntaxique pour une construction itérative plus puissante (itérateur). En termes simples, les boucles for dans Rust ne fonctionnent qu'avec des types qui peuvent être convertis en itérateurs. Un de ces types est le type Range. Le type Range peut faire référence à une série de nombres.
fn main() { print!("Plage normale : "); pour moi dans 0..10 { imprimer!("{},", je); } println!(); print!("Plage incluse : "); pour je dans 0..=10 { imprimer!("(),", je); } }
1.3.9 Types de données personnalisés
Les types personnalisés sont des types définis par les utilisateurs. Les types personnalisés peuvent être composés de plusieurs types. Ils peuvent être des wrappers autour de types primitifs ou une combinaison de plusieurs types personnalisés. Ils se présentent sous trois formes : structure, énumération et union, également appelées struct, enum et union. Ils vous permettent de représenter vos données plus facilement. Les règles de dénomination des types personnalisés suivent CamelCase.
Structure
Dans Rust, il existe trois formes de déclaration de structure. La plus simple d'entre elles est la structure unitaire, qui est déclarée à l'aide du mot-clé struct, suivi de son nom et se terminant par un point-virgule.
struct Factice ; fn main() { let value = Factice ; }
La deuxième forme de structure est la structure tuple, à laquelle sont associées des données. Chacun de ces champs n'est pas nommé, mais est référencé en fonction de sa position dans la définition.
struct Couleur(u8, u8, u8); fn main() { soit blanc = Couleur (255, 255, 255); soit rouge = blanc.0 ; soit vert = blanc.1 ; soit bleu = blanc.2 ; println!("Valeur rouge : {}", rouge); soit orange = Couleur (255, 165, 0); soit Color(r, g, b) = orange; println!("R : {}, G : {}, B : {} (orange)", r, g, b); soit Color(r, _, b) = orange; }
Les structures de tuples sont idéales lors de la modélisation de données avec moins de 5 attributs. Tout choix autre que celui-ci entravera la lisibilité et le raisonnement du code. Pour les types de données comportant plus de 3 champs, construisez des structures en utilisant un langage de type C. Il s'agit du troisième formulaire et du formulaire le plus couramment utilisé.
struct Joueur { nom : chaîne, QI : u8, amis : u8, note : U16 } fn bump_player_score(mut joueur : Joueur, score : u16) { joueur.score = score ; println!("Statistiques du joueur mises à jour :"); } fn main() { let name = "Alice".to_string(); let player = Joueur { nom, QI : 171, amis : 134, score : 1129} ; bump_player_score(joueur, 120); }
énumérer
Les énumérations sont un bon moyen de procéder lorsque vous devez modéliser différents types de choses. Il est créé à l'aide du mot-clé enum, suivi du nom de l'énumération et d'une paire d'accolades. À l’intérieur des accolades, nous pouvons écrire tous les types possibles, c’est-à-dire les variantes. Ces variantes peuvent être définies avec ou sans données, et les données contenues peuvent être de n'importe quel type far, structure, structure de tuple ou même un type d'énumération.
énumération Direction { N, E, S, W } enum PlayerAction { Se déplacer { Direction : Direction, Vitesse : u8 }, Attendez, Attaque (direction) } fn main() { laissez simulation_player_action = PlayerAction::Move { direction : Direction ::N, vitesse: 2, } ; match simulation_player_action { PlayerAction::Wait => println!("Le joueur veut attendre"), PlayerAction::Move {direction, vitesse} => { println!("Le joueur veut se déplacer dans la direction {:?} avec la vitesse {}", direction, vitesse) } PlayerAction::Attaque(direction) => { println!("Le joueur veut accéder à la direction {:?}", direction) } } ; }
1.3.10 Fonctions et méthodes sur les types
bloc impl sur la structure
Nous pouvons ajouter un comportement à une structure définie en utilisant deux mécanismes : des fonctions de type constructeur et des méthodes getter et setter.
struct Joueur { nom : chaîne, QI : u8, amis : u8 } impl Joueur { fn with_name(name: &str) -> Joueur { Joueur { nom : nom.to_string(), QI : 100, amis : 100 } } fn get_friends(&self) -> u8 { soi.amis } fn définir des amis (&mut soi-même, compte : u8) { self.friends = compter; } } fn main() { laissez mut player = Player::with_name("Dave"); joueur.set_friends(23); println!("Les amis de {} comptent : {}", player.name, player.get_friends()); let _ = Player::get_friends(&player); }
Méthode associée : Cette méthode n’a pas de type self comme premier paramètre. Cela ressemble aux méthodes statiques des langages de programmation orientés objet. Ces méthodes sont appelables sur le type lui-même et ne nécessitent pas d’appel d’instance du type. Une méthode associée est appelée en faisant précéder le nom de la méthode du nom de la structure suivi de deux points.
Méthode d'instance : une fonction qui prend self comme premier paramètre externe. Le self ici est similaire à self en Python et pointe vers l'instance qui implémente la méthode.
blocs et énumérations impl
Les énumérations sont largement utilisées dans les machines à états et, lorsqu'elles sont utilisées avec des expressions de correspondance, elles peuvent rendre le code de transition d'état très concis. Ils peuvent également être utilisés pour la modélisation de types d’erreurs personnalisés.
enum Mode de paiement { Débit, Crédit, Pay Pal } fn pay_by_credit(montant : u64) { println!("Traitement du paiement par crédit de {}", amt); } fn pay_by_debit(montant : u64) { println!("Traitement du paiement par débit de {}", amt); } fn paypal_redirect (montant : u64) { println!("Redirection vers Paypal pour le montant : {}", amt); } impl Mode de paiement { fn payer(&auto-même, montant : u64) { correspondre à soi { PaymentMode::Debit => pay_by_debit(montant), PaymentMode::Credit => pay_by_credit(montant), PaymentMode :: Paypal => paypal_redirect (montant) } } } fn get_saved_payment_mode() -> PaymentMode { Mode de paiement : Débit } fn main() { let payment_mode = get_saved_payment_mode(); payment_mode.pay(512); }
1.3.11 module, instructions d'importation et d'utilisation
Les langages de programmation offrent souvent un moyen de diviser de gros blocs de code en plusieurs fichiers pour gérer la complexité. Java suit la convention selon laquelle chaque fichier .java est une classe publique, et C nous fournit des fichiers d'en-tête et des instructions d'inclusion. Rust fournit un mécanisme de module. Les modules sont un moyen de nommer et d'organiser le code dans les programmes Rust.
Chaque programme Rust nécessite un module racine. Pour les fichiers exécutables, il s'agit généralement du fichier main.rs, et pour les bibliothèques, il s'agit généralement du fichier lib.rs.
Les modules peuvent être déclarés dans d'autres modules ou organisés en fichiers et répertoires.
Pour que le compilateur reconnaisse notre module, nous devons utiliser le mot-clé mod déclaration. Dans notre module racine, nous devons utiliser le mot-clé use avant le nom du module, ce qui signifie amener l'élément dans la portée.
Les éléments définis dans un module sont privés par défaut et doivent être exposés aux appelants à l'aide du mot-clé pub.
1.3.12 Collecte
tableau
Les tableaux ont une longueur fixe et peuvent stocker des éléments du même type. Ils sont représentés par [T, N], où T représente n'importe quel type et N représente le nombre d'éléments du tableau. La taille du tableau ne peut pas être représentée par une variable et doit être une valeur littérale de usize.
tuple
Liste des projets
paire clé/valeur
tranche
1.3.13 Itérateur
sous-thème
sous-thème
sous-thème
1.4 Améliorer le compteur de caractères
1.5 Résumé
Chapitre 2 Utiliser Cargo pour gérer des projets
2.1 Gestionnaire de paquets
2.2Modules
2.2.1 Modules imbriqués
2.2.2 Utiliser des fichiers comme modules
2.2.3 Utiliser des répertoires comme modules
2.3 Cargo et bibliothèques
2.3.1 Créer un nouveau projet Cargo
2.3.2 Cargaison et dépendances
2.3.3 Utiliser Cargo pour exécuter des tests
2.3.4 Utilisation de Cargo pour exécuter l'exemple
2.3.5 Espace de travail de chargement
2.4 Extension de l'outil de chargement
2.4.1 Sous-commandes et installation de Cargo
2.4.2 Utiliser Clippy pour formater le code
2.4.3 Introduction au fichier manifeste Cargo.toml
2.5 Mettre en place un environnement de développement Rust
2.6 Utiliser Cargo pour créer le programme imgtool
2.7 Résumé
Chapitre 3 Tests, documentation et analyse comparative
3.1 Objectif des tests
3.2 Organisation des tests
3.3 Tests unitaires
3.3.1 Le premier test unitaire
3.3.2 Exécution de tests
3.3.3 Isoler le code de test
3.3.4 Tests de défaillance
3..3.5 Ignorer les tests
3.4 Tests d'intégration
3.4.1 Premier test d'intégration
3.4.2 Partage de code commun
3.5Documents
3.5.1 Rédaction de documents
3.5.2 Générer et afficher des documents
3.5.3 Documents hébergés
3.5.4 Propriétés du document
3.5.5 Tests documentés
3.6 Évaluation
3.6.1 Outils de micro-benchmark intégrés
3.6.2 Benchmarking sur la version stable de Rust
3.7 Ecriture et test de progiciels - simulateur de portes logiques
3.8 Tests d'intégration CI et Travis CI
3.9 Résumé
Chapitre 4 Types, génériques et traits
4.1 Systèmes de types et leur importance
4.2 Génériques
4.2.1 Création de génériques#
4.2.2 Implémentation générique
4.2.3 Applications génériques
4.3 Utiliser des fonctionnalités pour abstraire le comportement
4.3.1 Caractéristiques
4.3.2 Diverses formes de fonctionnalités
4.4 Utilisation des fonctionnalités génériques du package – intervalles de fonctionnalités
4.4.1 Intervalles caractéristiques sur les types
4.4.2 Intervalles caractéristiques sur les fonctions génériques et les blocs de code impl
4.4.3 Utiliser la combinaison de fonctionnalités « » pour former un intervalle
4.4.4 Intervalle de fonctionnalité et syntaxe de fonctionnalité impl
4.5 Introduction aux fonctionnalités de la bibliothèque standard
4.6 Utiliser des objets de trait pour obtenir un véritable polymorphisme
4.6.1 Répartition
4.6.2 Objets caractéristiques
4.7 Résumé
Chapitre 5 Gestion de la mémoire et sécurité
5.1 Programmes et mémoire
5.2 Comment les programmes utilisent la mémoire
5.3 Gestion et classification de la mémoire
5.4 Introduction à l'allocation de mémoire
5.4.1 Pile
5.4.2 Tas
5.5 Défauts dans la gestion de la mémoire
5.6 Sécurité de la mémoire
5.7 Trois principes de sécurité de la mémoire
5.7.1 Propriété
5.7.2 Réutilisation de types via des traits
5.7.3 Emprunt
5.7.4 Types de méthodes basés sur des règles d'emprunt
5.7.5 Cycle de vie
5.8 Types de pointeurs dans Rust
5.8.1 Références – pointeurs sûrs
5.8.2 Pointeurs bruts
5.8.3 Pointeurs intelligents
5.8.4 Pointeurs intelligents à comptage de références
5.8.5 Application de la variabilité interne
5.9 Résumé
Chapitre 6 Gestion des exceptions
6.1 Introduction à la gestion des exceptions
6.2 Exceptions récupérables
6.2.1 Options
6.2.2 Résultat
6.3 Combinaison Option/Résultat
6.3.1 Combinateurs courants
6.3.2 Application du combineur
6.3.3 Conversion entre les types Option et Résultat
6.4 Retour anticipé et opérateur "?"
6.5 Exceptions irrécupérables
6.6 Erreurs personnalisées et caractéristiques des erreurs
6.7 Résumé
Chapitre 7 Concepts avancés
7.1 Introduction aux systèmes de types
7.1.1 Blocs de code et expressions
7.1.2 Instruction let
7.1.3 Boucles comme expressions
7.1.4 Clarté des types et distinction des symboles dans les types numériques
7.1.5 Inférence de type
7.1.6 Alias de type
7.2 Chaîne
7.2.1 Chaîne contenant la propriété - Chaîne
7.2.2 Chaîne d'emprunt——&str
7.2.3 Découpage et fragmentation de chaînes
7.2.4 Utilisation de chaînes dans les fonctions
7.2.5 Concaténation de chaînes
7.2.6 Scénarios d'application de &str et String
7.3 Valeurs globales
7.3.1 Constantes
7.3.2 Valeurs statiques
7.3.3 Fonction au moment de la compilation——const fn
7.3.4 Valeurs statiques dynamiques via la macro lazy_static
7.4 Itérateurs
7.5 Types avancés
7.5.1 Types de longueur indéfinie
7.5.2 Types de fonctions
7.5.3 ne jamais taper « ! » et envoyer des fonctions
7.5.4 Syndicat
7.5.5 Vache
7.6 Fonctionnalités avancées
7.6.1 Dimensionné et ?Dimensionné
7.6.2 Emprunter et AsRef
7.6.3 Désossé
7.6.4 De et vers
7.6.5 Objets caractéristiques et sécurité des objets
7.6.6 Syntaxe générale des appels de fonctions
7.6.7 Règles de fonctionnalité
7.7 Fermetures avancées
7.7.1 Fermeture Fn
7.7.2 Fermeture FnMut
7.7.3 Fermeture FnUne fois
7.8 Constantes dans les structures, les énumérations et les traits
7.9 Modules, chemins et importations
7.9.1 Importer
7.9.2 Importer à nouveau
7.9.3 Confidentialité
7.10 Modèles de correspondance avancés et gardes
7.10.1 Garde-match
7.10.2 Construction de let avancée
7.11 Casting
7.12 Types et mémoire
7.12.1 Alignement de la mémoire
7.12.2 module std::mem
7.13 Sérialisation et désérialisation à l'aide de serde
7.14 Résumé
Chapitre 8 Concurrence
8.1 Modèle d'exécution du programme
8.2 Concurrence
8.2.1 Méthodes concurrentes
8.2.2 Défauts
8.3 Concurrence dans Rust
8.3.1 Bases du fil de discussion
8.3.2 Fils personnalisés
8.3.3 Accès aux données dans les threads
8.4 Modèle de concurrence de threads
8.4.1 Modèle de partage d'état
8.4.2 Exclusion mutuelle
8.4.3 Mutabilité partagée via Arc et Mutex
8.4.4 Communication par messagerie
8.5 Sécurité des threads dans Rust
8.5.1 Qu'est-ce que la sécurité des threads ?
8.5.2 Caractéristiques de la sécurité des filetages
8.5.3 Envoyer
8.5.4 Synchronisation
8.6 Implémentation de la concurrence à l'aide du modèle d'acteur
8.7 Autres bibliothèques
8.8 Résumé
Chapitre 9 Macros et métaprogrammation
9.1 Qu'est-ce que la métaprogrammation ?
9.2 Scénarios d'application des macros Rust
9.3 Macros et leurs types dans Rust
9.4 Créez des macros à l'aide de macro_rules !
9.5 Macros intégrées dans la bibliothèque standard
9.6 macro_rules !
9.7 Répétition dans les macros
9.8 Application avancée des macros - écriture de DSL pour l'initialisation de HashMap
9.9 Cas d'utilisation de macros - tests d'écriture
9.10 Exercice
9.11 Macros de processus
9.12 Macros dérivées
9.13 Macros de haut niveau
9.14 Progiciels de macros de processus couramment utilisés
9.15 Résumé
Chapitre 10 Interfaces Rust et fonctions étrangères dangereuses
10.1 Sécurité et danger
10.1.1 Fonctions et blocs de codes non sécurisés
10.1.2 Caractéristiques et implémentations dangereuses
10.2 Appeler du code C dans Rust
10.3 Appel du code Rust via le langage C
10.4 Utilisation de bibliothèques C/C externes dans Rust
10.5 Construction d'extensions Python natives à l'aide de PyO3
10.6 Création d'extensions natives pour Node.js dans Rust
10.7 Résumé
Journal du chapitre 11
11.1 L'exploitation forestière et son importance
11.2 Exigences pour un cadre de journalisation
11.3 Cadre de journalisation et ses fonctionnalités
11.4 Méthode de journalisation
11.4.1 Journalisation non structurée
11.4.2 Journalisation structurée
11.5 Connexion à Rust
Journal 11.5.1 – Journalisation pour Rust
11.5.2 env_logger
11.5.3 log4rs
11.5.4 Utilisation de slog pour la journalisation structurée
11.6 Résumé
Chapitre 12 Rust et la programmation réseau
12.1 Introduction à la programmation réseau
12.2 E/S réseau synchrone
12.3 E/S réseau asynchrone
12.3.1 Abstractions asynchrones dans Rust
12.3.2 Création d'un serveur Redis asynchrone
12.4 Résumé
Chapitre 13 Création d'applications Web avec Rust
13.1 Applications Web dans Rust
13.2 Utilisation d'hyper pour la communication HTTP
13.2.1 L'API côté serveur Hyper crée un service d'URL courte
13.2.2 Hyper en tant que client - création d'un client URL court
13.2.3 Cadre Web
13.3 Connaissances de base d'Actix-web
13.4 Création d'une API de favoris à l'aide d'actix-web
13.5 Résumé
Chapitre 14 Rust et WebAssembly
14.1 L'importance de la durabilité des données
14.2 SQLite
14.3 PostgreSQL
14.4 Pool de connexions r2d2
14.5 Postgres et ORM diesel
14.6 Résumé
Chapitre 15 Rust et WebAssembly
15.1 Qu'est-ce que WebAssmbly
15.2 Objectifs de conception de WebAssembly
15.3 Démarrer avec WebAssembly
15.3.1 Essayez en ligne
15.3.2 Méthodes pour générer WebAssembly
15.4 Rust et WebAssembly
15.4.1 wasm-bindgen
15.4.2 Autres projets WebAssembly
15.5 Résumé
Chapitre 16 Rust et applications de bureau
16.1 Introduction au développement d'interface graphique
16.2 Cadre GTK
16.3 Créer une application de bureau d'actualités via gtk-rs
16.4 Exercices
16.5 Autres cadres d'interface utilisateur émergents
16.6 Résumé
Chapitre 17 Débogage
17.1 Introduction au débogage
17.1.1 Notions de base du débogueur
17.1.2 Conditions préalables à la mise en service
17.1.3 Configuration de GDB
17.1.4 Un exemple de programme : buggie
17.1.5 Bases de GDB
17.1.6 Intégration de GDB dans Visual Studio Code
17.2 Introduction au débogueur rr
17.3 Résumé