1
0
mirror of https://github.com/google/comprehensive-rust.git synced 2024-11-21 13:25:53 +02:00

Simplify language, add links, formatting fixes (#2443)

- Avoid time-specific statements (“recently”, “today”, …).

- Move details such as “RPIT” to the speaker notes.

- More links to our slides as well as community documentation.

- Formatting fixes
This commit is contained in:
Martin Geisler 2024-10-18 03:03:17 -04:00 committed by GitHub
parent 5d292377a0
commit 47c3d50542
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194

View File

@ -4,22 +4,20 @@ minutes: 5
# Async Traits
Async methods in traits are were stabilized only recently, in the 1.75 release.
This required support for using return-position `impl Trait` (RPIT) in traits,
as the desugaring for `async fn` includes `-> impl Future<Output = ...>`.
Async methods in traits are were stabilized in the 1.75 release. This required
support for using return-position `impl Trait` in traits, as the desugaring for
`async fn` includes `-> impl Future<Output = ...>`.
However, even with the native support today there are some pitfalls around
`async fn` and RPIT in traits:
However, even with the native support, there are some pitfalls around
`async fn`:
- Return-position impl Trait captures all in-scope lifetimes (so some patterns
of borrowing cannot be expressed)
- Return-position `impl Trait` captures all in-scope lifetimes (so some patterns
of borrowing cannot be expressed).
- Traits whose methods use return-position `impl trait` or `async` are not `dyn`
compatible.
- Async traits cannot be used with [trait objects] (`dyn Trait` support).
If we do need `dyn` support, the crate
[async_trait](https://docs.rs/async-trait/latest/async_trait/) provides a
workaround through a macro, with some caveats:
The [async_trait] crate provides a workaround for `dyn` support through a macro,
with some caveats:
```rust,editable,compile_fail
use async_trait::async_trait;
@ -47,11 +45,11 @@ async fn run_all_sleepers_multiple_times(
n_times: usize,
) {
for _ in 0..n_times {
println!("running all sleepers..");
println!("Running all sleepers...");
for sleeper in &sleepers {
let start = Instant::now();
sleeper.sleep().await;
println!("slept for {}ms", start.elapsed().as_millis());
println!("Slept for {} ms", start.elapsed().as_millis());
}
}
}
@ -71,13 +69,21 @@ async fn main() {
- `async_trait` is easy to use, but note that it's using heap allocations to
achieve this. This heap allocation has performance overhead.
- The challenges in language support for `async trait` are deep Rust and
probably not worth describing in-depth. Niko Matsakis did a good job of
explaining them in
[this post](https://smallcultfollowing.com/babysteps/blog/2019/10/26/async-fn-in-traits-are-hard/)
if you are interested in digging deeper.
- The challenges in language support for `async trait` are too deep to describe
in-depth in this class. See [this blog post] by Niko Matsakis if you are
interested in digging deeper. See also these keywords:
- [RPIT]: short for
[return-position `impl Trait`](../../generics/impl-trait.md).
- [RPITIT]: short for return-position `impl Trait` in trait (RPIT in trait).
- Try creating a new sleeper struct that will sleep for a random amount of time
and adding it to the Vec.
and adding it to the `Vec`.
</details>
[async_trait]: https://docs.rs/async-trait/
[trait objects]: ../../smart-pointers/trait-objects.md
[this blog post]: https://smallcultfollowing.com/babysteps/blog/2019/10/26/async-fn-in-traits-are-hard/
[RPIT]: https://doc.rust-lang.org/reference/types/impl-trait.html#abstract-return-types
[RPITIT]: https://blog.rust-lang.org/2023/12/21/async-fn-rpit-in-traits.html