mirror of
https://github.com/rust-lang/rustlings.git
synced 2026-05-15 17:58:44 +00:00
Merge 91fd773859d319f9c94afc160ee5e867a70755e8 into 1d53bd1b54cf8ccf7638862be43d9ae2c964c9ea
This commit is contained in:
commit
5cc1983752
@ -188,6 +188,8 @@ bin = [
|
|||||||
{ name = "try_from_into_sol", path = "../solutions/23_conversions/try_from_into.rs" },
|
{ name = "try_from_into_sol", path = "../solutions/23_conversions/try_from_into.rs" },
|
||||||
{ name = "as_ref_mut", path = "../exercises/23_conversions/as_ref_mut.rs" },
|
{ name = "as_ref_mut", path = "../exercises/23_conversions/as_ref_mut.rs" },
|
||||||
{ name = "as_ref_mut_sol", path = "../solutions/23_conversions/as_ref_mut.rs" },
|
{ name = "as_ref_mut_sol", path = "../solutions/23_conversions/as_ref_mut.rs" },
|
||||||
|
{ name = "async1", path = "../exercises/24_async/async1.rs" },
|
||||||
|
{ name = "async1_sol", path = "../solutions/24_async/async1.rs" },
|
||||||
]
|
]
|
||||||
|
|
||||||
[package]
|
[package]
|
||||||
@ -196,6 +198,9 @@ edition = "2024"
|
|||||||
# Don't publish the exercises on crates.io!
|
# Don't publish the exercises on crates.io!
|
||||||
publish = false
|
publish = false
|
||||||
|
|
||||||
|
[dependencies]
|
||||||
|
tokio = { version = "1", features = ["rt"] }
|
||||||
|
|
||||||
[profile.release]
|
[profile.release]
|
||||||
panic = "abort"
|
panic = "abort"
|
||||||
|
|
||||||
|
|||||||
13
exercises/24_async/README.md
Normal file
13
exercises/24_async/README.md
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
# Async
|
||||||
|
|
||||||
|
Asynchronous programming is a model where tasks are delegated to a runtime that executes them concurrently.
|
||||||
|
It is particularly efficient for applications where many independent IO-operations are performed, e.g. web servers.
|
||||||
|
|
||||||
|
Rust provides the necessary primitives to do asynchronous programming in the language.
|
||||||
|
However, Rust's standard library does not include a runtime.
|
||||||
|
For these exercises, we will use the mainstream runtime called `tokio`.
|
||||||
|
|
||||||
|
## Further information
|
||||||
|
|
||||||
|
- [Fundamentals of Asynchronous Programming](https://doc.rust-lang.org/book/ch17-00-async-await.html)
|
||||||
|
- [Tokio documentation](https://docs.rs/tokio/latest/tokio/)
|
||||||
42
exercises/24_async/async1.rs
Normal file
42
exercises/24_async/async1.rs
Normal file
@ -0,0 +1,42 @@
|
|||||||
|
// Alice is an elementary school teacher who needs to calculate the mean test
|
||||||
|
// score for three classes she teaches. Instead of calculating them one after
|
||||||
|
// the other, she decides to ask her friends Bob and Catherine for help. Working
|
||||||
|
// together, they can finish the job much faster.
|
||||||
|
//
|
||||||
|
// Let's simulate this using asynchronous programming. Each person is
|
||||||
|
// represented as an asynchronous task, which can be executed concurrently (i.e.
|
||||||
|
// they can be doing the calculations at the same time).
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
// Async tasks need to be executed by a "runtime", which is not provided by
|
||||||
|
// Rust's standard library. Here, we use the mainstream runtime `tokio`.
|
||||||
|
let rt = tokio::runtime::Builder::new_current_thread()
|
||||||
|
.build()
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
|
let scores_class_a = &[83, 77, 92];
|
||||||
|
let scores_class_b = &[84, 88, 96];
|
||||||
|
let scores_class_c = &[71, 83, 76];
|
||||||
|
|
||||||
|
// TODO: Fix the compiler errors by making the spawned function async.
|
||||||
|
let alice = rt.spawn(calculate_mean_score(scores_class_a));
|
||||||
|
let bob = rt.spawn(calculate_mean_score(scores_class_b));
|
||||||
|
let catherine = rt.spawn(calculate_mean_score(scores_class_c));
|
||||||
|
|
||||||
|
// Block the runtime on a task that awaits all three calculations.
|
||||||
|
let [mean_score_a, mean_score_b, mean_score_c]: [usize; _] = rt.block_on(async {
|
||||||
|
[
|
||||||
|
// TODO: "await" all three tasks to fix the compiler error.
|
||||||
|
alice, bob, catherine,
|
||||||
|
]
|
||||||
|
});
|
||||||
|
|
||||||
|
assert_eq!(mean_score_a, 84);
|
||||||
|
assert_eq!(mean_score_b, 89);
|
||||||
|
assert_eq!(mean_score_c, 76);
|
||||||
|
}
|
||||||
|
|
||||||
|
fn calculate_mean_score(score_list: &[usize]) -> usize {
|
||||||
|
let score_sum: usize = score_list.iter().sum();
|
||||||
|
score_sum / score_list.len()
|
||||||
|
}
|
||||||
@ -1199,3 +1199,17 @@ name = "as_ref_mut"
|
|||||||
dir = "23_conversions"
|
dir = "23_conversions"
|
||||||
hint = """
|
hint = """
|
||||||
Add `AsRef<str>` or `AsMut<u32>` as a trait bound to the functions."""
|
Add `AsRef<str>` or `AsMut<u32>` as a trait bound to the functions."""
|
||||||
|
|
||||||
|
# ASYNC
|
||||||
|
|
||||||
|
[[exercises]]
|
||||||
|
name = "async1"
|
||||||
|
dir = "24_async"
|
||||||
|
test = false
|
||||||
|
hint = """
|
||||||
|
Asynchronous runtimes like tokio can only spawn tasks that are defined as async
|
||||||
|
functions, not regular ones. Add the "async" keyword before the "fn" keyword of
|
||||||
|
the functions "tim", "carl" and "nick".
|
||||||
|
|
||||||
|
An async task can wait for another one to complete by "awaiting" it. Add
|
||||||
|
".await" after the three "task_name" variables in the "block_on" call."""
|
||||||
|
|||||||
42
solutions/24_async/async1.rs
Normal file
42
solutions/24_async/async1.rs
Normal file
@ -0,0 +1,42 @@
|
|||||||
|
// Alice is an elementary school teacher who needs to calculate the mean test
|
||||||
|
// score for three classes she teaches. Instead of calculating them one after
|
||||||
|
// the other, she decides to ask her friends Bob and Catherine for help. Working
|
||||||
|
// together, they can finish the job much faster.
|
||||||
|
//
|
||||||
|
// Let's simulate this using asynchronous programming. Each person is
|
||||||
|
// represented as an asynchronous task, which can be executed concurrently (i.e.
|
||||||
|
// they can be doing the calculations at the same time).
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
// Async tasks need to be executed by a "runtime", which is not provided by
|
||||||
|
// Rust's standard library. Here, we use the mainstream runtime `tokio`.
|
||||||
|
let rt = tokio::runtime::Builder::new_current_thread()
|
||||||
|
.build()
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
|
let scores_class_a = &[83, 77, 92];
|
||||||
|
let scores_class_b = &[84, 88, 96];
|
||||||
|
let scores_class_c = &[71, 83, 76];
|
||||||
|
|
||||||
|
let alice = rt.spawn(calculate_mean_score(scores_class_a));
|
||||||
|
let bob = rt.spawn(calculate_mean_score(scores_class_b));
|
||||||
|
let catherine = rt.spawn(calculate_mean_score(scores_class_c));
|
||||||
|
|
||||||
|
// Block the runtime on a task that awaits all three calculations.
|
||||||
|
let [mean_score_a, mean_score_b, mean_score_c]: [usize; _] = rt.block_on(async {
|
||||||
|
[
|
||||||
|
alice.await.unwrap(),
|
||||||
|
bob.await.unwrap(),
|
||||||
|
catherine.await.unwrap(),
|
||||||
|
]
|
||||||
|
});
|
||||||
|
|
||||||
|
assert_eq!(mean_score_a, 84);
|
||||||
|
assert_eq!(mean_score_b, 89);
|
||||||
|
assert_eq!(mean_score_c, 76);
|
||||||
|
}
|
||||||
|
|
||||||
|
async fn calculate_mean_score(score_list: &[usize]) -> usize {
|
||||||
|
let score_sum: usize = score_list.iter().sum();
|
||||||
|
score_sum / score_list.len()
|
||||||
|
}
|
||||||
Loading…
x
Reference in New Issue
Block a user