Bloqué sur la syntaxe async/await de Rust, des ressources à recommander ?

J'essaie d'apprendre Rust depuis un mois et je me heurte constamment à un mur avec async/await. À chaque fois que j'essaie d'écrire une fonction async qui appelle une autre fonction async, j'obtiens ces erreurs de durée de vie confuses. Est-ce qu'il y a de bons tutoriels ou des patterns qui expliquent vraiment ça en langage simple au lieu de messages d'erreur du compilateur ?

4 réponses

★ Meilleure réponse

Les erreurs de durée de vie ne sont pas réellement le mur sur lequel tu t'écrases - ce sont des symptômes de quelque chose de plus simple. Avant de te perdre dans le vérificateur d'emprunts, essaye ceci : écris tes fonctions async avec des types de retour explicites `Box<dyn Future<Output = YourType>>` au lieu de la syntaxe `impl Future`, du moins le temps d'apprendre. Ça te force à voir exactement ce qui est capturé et rend le compilateur moins énigmatique sur ce qui échoue réellement. Une fois que tu as une version qui fonctionne de cette façon, tu peux refactoriser pour revenir à `impl Future` et comprendre *pourquoi* le compilateur l'accepte maintenant, au lieu de juste tweaker les choses jusqu'à ce que les erreurs disparaissent.

Tu utilises `.await` là où tu appelles les fonctions, ou tu appelles juste la fonction async sans l'attendre ? Les erreurs de durée de vie se résument souvent à ce que le compilateur voit une référence empruntée qui vit moins longtemps que ce dont la future a besoin - ce n'est pas de la magie async, c'est juste le borrow checker de Rust qui fait son travail à travers les points await. Le livre officiel Async Rust (sur le site de Rust) a une section qui détaille exactement ça, et c'est vraiment plus clair que la plupart des tutoriels. Si tu cherches des messages d'erreur spécifiques, essaie d'isoler un petit exemple qui échoue, poste-le sur r/rust ou le forum Rust - les gens là-bas sont patients pour expliquer le problème réel plutôt que le bruit de l'erreur.

James_1984 asker Ouais, j'utilise `.await` aux points d'appel. Le borrow checker à travers les points await a du sens - je vais consulter cette section du livre Async Rust.

arrête de combattre le borrow checker et pense plutôt à async/await comme créer une machine à états - chaque point d'await est essentiellement une pause où rust doit savoir quelles données survivent jusqu'à la pause suivante. c'est pour ça que tu obtiens des erreurs de lifetime. le compilateur n'est pas obtus, il est vraiment incertain si tes données empruntées seront encore valides quand l'exécution reprendra.

le bouquin async officiel de rust (rust-lang.org/what/wasm/book) est vraiment solide pour ça, mais ce qui m'a le plus aidée c'était de lire le tutoriel de tokio parce qu'il utilise des vrais exemples au lieu de théorie abstraite. la série vidéo de Jon Gjengset sur youtube sur l'async rust déclenche le déclic chez beaucoup de gens aussi - il parcourt le modèle mental étape par étape au lieu de te balancer la syntaxe directement. un pattern qui a démystifié les choses pour moi : quand tu chaînes des appels async, appuie-toi sur `tokio::spawn` ou utilise les chaînes `.await` de façon cohérente pour que tu ne mélandes pas les références empruntées avec les limites async.

un truc pratique à essayer - écris ce que ta fonction async a réellement besoin de garder à travers les awaits, puis passe uniquement ça explicitement. ne passe pas de références si tu peux passer des valeurs possédées. ouais ça fait gaspilleur parfois mais ça te force à comprendre le problème de lifetime au lieu de combattre les messages d'erreur. et joue aussi dans le playground (play.rust-lang.org) avec de minuscules exemples avant de t'attaquer au vrai code - parfois un cas de test de 5 lignes révèle ce qui se passe vraiment plus vite que de déboguer ton projet principal.

Ce qui a vraiment déclenché l'électricité pour moi, c'est de réaliser que les fonctions async ne retournent pas vraiment ce que tu vois dans la signature - elles retournent une Future qui *va* éventuellement produire cette valeur, et le borrow checker a besoin de savoir que chaque référence que tu utilises sera toujours valide quand cette Future s'exécutera réellement. J'ai passé des semaines à me battre avec des erreurs de lifetime dans des appels async imbriqués jusqu'à ce que je commence à écrire sur quelles données chaque point `.await` dépendait, presque comme si je racontais le cycle de vie de la Future à voix haute. Essaie le tutoriel Tokio et surtout leur section sur le spawning de tâches - voir des exemples concrets de ce qui se déplace dans une tâche spawnée versus ce qui est emprunté à travers les points await a aidé bien plus que des explications abstraites. Le chapitre async du Rust book s'est aussi amélioré, donc ne le saute pas même si tu as déjà lu des parties du livre principal.

Votre réponse

Se connecterpour répondre.