mirror of
https://github.com/rust-lang/rustlings.git
synced 2025-12-28 06:49:19 +00:00
update codes
This commit is contained in:
parent
a8bcac9c6f
commit
2c7f64424c
240
Cargo.lock
generated
240
Cargo.lock
generated
@ -2,21 +2,6 @@
|
||||
# It is not intended for manual editing.
|
||||
version = 3
|
||||
|
||||
[[package]]
|
||||
name = "addr2line"
|
||||
version = "0.22.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6e4503c46a5c0c7844e948c9a4d6acd9f50cccb4de1c48eb9e291ea17470c678"
|
||||
dependencies = [
|
||||
"gimli",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "adler"
|
||||
version = "1.0.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe"
|
||||
|
||||
[[package]]
|
||||
name = "ahash"
|
||||
version = "0.8.11"
|
||||
@ -120,21 +105,6 @@ version = "1.3.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0c4b4d0bd25bd0b74681c0ad21497610ce1b7c91b1022cd21c80c6fbdd9476b0"
|
||||
|
||||
[[package]]
|
||||
name = "backtrace"
|
||||
version = "0.3.73"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5cc23269a4f8976d0a4d2e7109211a419fe30e8d88d677cd60b6bc79c5732e0a"
|
||||
dependencies = [
|
||||
"addr2line",
|
||||
"cc",
|
||||
"cfg-if",
|
||||
"libc",
|
||||
"miniz_oxide",
|
||||
"object",
|
||||
"rustc-demangle",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "bitflags"
|
||||
version = "1.3.2"
|
||||
@ -158,12 +128,6 @@ dependencies = [
|
||||
"serde",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "bytes"
|
||||
version = "1.6.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "514de17de45fdb8dc022b1a7975556c53c86f9f0aa5f534b98977b171857c2c9"
|
||||
|
||||
[[package]]
|
||||
name = "cassowary"
|
||||
version = "0.3.0"
|
||||
@ -179,12 +143,6 @@ dependencies = [
|
||||
"rustversion",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "cc"
|
||||
version = "1.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "eaff6f8ce506b9773fa786672d63fc7a191ffea1be33f72bbd4aeacefca9ffc8"
|
||||
|
||||
[[package]]
|
||||
name = "cfg-if"
|
||||
version = "1.0.0"
|
||||
@ -344,101 +302,6 @@ dependencies = [
|
||||
"libc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "futures"
|
||||
version = "0.3.30"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "645c6916888f6cb6350d2550b80fb63e734897a8498abe35cfb732b6487804b0"
|
||||
dependencies = [
|
||||
"futures-channel",
|
||||
"futures-core",
|
||||
"futures-executor",
|
||||
"futures-io",
|
||||
"futures-sink",
|
||||
"futures-task",
|
||||
"futures-util",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "futures-channel"
|
||||
version = "0.3.30"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "eac8f7d7865dcb88bd4373ab671c8cf4508703796caa2b1985a9ca867b3fcb78"
|
||||
dependencies = [
|
||||
"futures-core",
|
||||
"futures-sink",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "futures-core"
|
||||
version = "0.3.30"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "dfc6580bb841c5a68e9ef15c77ccc837b40a7504914d52e47b8b0e9bbda25a1d"
|
||||
|
||||
[[package]]
|
||||
name = "futures-executor"
|
||||
version = "0.3.30"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a576fc72ae164fca6b9db127eaa9a9dda0d61316034f33a0a0d4eda41f02b01d"
|
||||
dependencies = [
|
||||
"futures-core",
|
||||
"futures-task",
|
||||
"futures-util",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "futures-io"
|
||||
version = "0.3.30"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a44623e20b9681a318efdd71c299b6b222ed6f231972bfe2f224ebad6311f0c1"
|
||||
|
||||
[[package]]
|
||||
name = "futures-macro"
|
||||
version = "0.3.30"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "87750cf4b7a4c0625b1529e4c543c2182106e4dedc60a2a6455e00d212c489ac"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "futures-sink"
|
||||
version = "0.3.30"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9fb8e00e87438d937621c1c6269e53f536c14d3fbd6a042bb24879e57d474fb5"
|
||||
|
||||
[[package]]
|
||||
name = "futures-task"
|
||||
version = "0.3.30"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "38d84fa142264698cdce1a9f9172cf383a0c82de1bddcf3092901442c4097004"
|
||||
|
||||
[[package]]
|
||||
name = "futures-util"
|
||||
version = "0.3.30"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3d6401deb83407ab3da39eba7e33987a73c3df0c82b4bb5813ee871c19c41d48"
|
||||
dependencies = [
|
||||
"futures-channel",
|
||||
"futures-core",
|
||||
"futures-io",
|
||||
"futures-macro",
|
||||
"futures-sink",
|
||||
"futures-task",
|
||||
"memchr",
|
||||
"pin-project-lite",
|
||||
"pin-utils",
|
||||
"slab",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "gimli"
|
||||
version = "0.29.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "40ecd4077b5ae9fd2e9e169b102c6c330d0605168eb0e8bf79952b256dbefffd"
|
||||
|
||||
[[package]]
|
||||
name = "hashbrown"
|
||||
version = "0.14.5"
|
||||
@ -455,12 +318,6 @@ version = "0.5.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea"
|
||||
|
||||
[[package]]
|
||||
name = "hermit-abi"
|
||||
version = "0.3.9"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d231dfb89cfffdbc30e7fc41579ed6066ad03abda9e567ccafae602b97ec5024"
|
||||
|
||||
[[package]]
|
||||
name = "indexmap"
|
||||
version = "2.2.6"
|
||||
@ -569,15 +426,6 @@ version = "2.7.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "78ca9ab1a0babb1e7d5695e3530886289c18cf2f87ec19a575a0abdce112e3a3"
|
||||
|
||||
[[package]]
|
||||
name = "miniz_oxide"
|
||||
version = "0.7.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b8a240ddb74feaf34a79a7add65a741f3167852fba007066dcac1ca548d89c08"
|
||||
dependencies = [
|
||||
"adler",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "mio"
|
||||
version = "0.8.11"
|
||||
@ -634,25 +482,6 @@ dependencies = [
|
||||
"autocfg",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "num_cpus"
|
||||
version = "1.16.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4161fcb6d602d4d2081af7c3a45852d875a03dd337a6bfdd6e06407b61342a43"
|
||||
dependencies = [
|
||||
"hermit-abi",
|
||||
"libc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "object"
|
||||
version = "0.36.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "081b846d1d56ddfc18fdf1a922e4f6e07a11768ea1b92dec44e42b72712ccfce"
|
||||
dependencies = [
|
||||
"memchr",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "once_cell"
|
||||
version = "1.19.0"
|
||||
@ -698,18 +527,6 @@ version = "1.0.15"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "57c0d7b74b563b49d38dae00a0c37d4d6de9b432382b2892f0574ddcae73fd0a"
|
||||
|
||||
[[package]]
|
||||
name = "pin-project-lite"
|
||||
version = "0.2.14"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "bda66fc9667c18cb2758a2ac84d1167245054bcf85d5d1aaa6923f45801bdd02"
|
||||
|
||||
[[package]]
|
||||
name = "pin-utils"
|
||||
version = "0.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184"
|
||||
|
||||
[[package]]
|
||||
name = "predicates"
|
||||
version = "3.1.0"
|
||||
@ -826,12 +643,6 @@ version = "0.8.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7a66a03ae7c801facd77a29370b4faec201768915ac14a721ba36f20bc9c209b"
|
||||
|
||||
[[package]]
|
||||
name = "rustc-demangle"
|
||||
version = "0.1.24"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "719b953e2095829ee67db738b3bfa9fa368c94900df327b3f07fe6e794d2fe1f"
|
||||
|
||||
[[package]]
|
||||
name = "rustlings"
|
||||
version = "6.1.0"
|
||||
@ -840,7 +651,6 @@ dependencies = [
|
||||
"assert_cmd",
|
||||
"clap",
|
||||
"crossterm",
|
||||
"futures",
|
||||
"hashbrown",
|
||||
"notify-debouncer-mini",
|
||||
"os_pipe",
|
||||
@ -849,7 +659,6 @@ dependencies = [
|
||||
"rustlings-macros",
|
||||
"serde",
|
||||
"serde_json",
|
||||
"tokio",
|
||||
"toml_edit",
|
||||
]
|
||||
|
||||
@ -959,31 +768,12 @@ dependencies = [
|
||||
"libc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "slab"
|
||||
version = "0.4.9"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8f92a496fb766b417c996b9c5e57daf2f7ad3b0bebe1ccfca4856390e3d3bb67"
|
||||
dependencies = [
|
||||
"autocfg",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "smallvec"
|
||||
version = "1.13.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3c5e1a9a646d36c3599cd173a41282daf47c44583ad367b8e6837255952e5c67"
|
||||
|
||||
[[package]]
|
||||
name = "socket2"
|
||||
version = "0.5.7"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ce305eb0b4296696835b71df73eb912e0f1ffd2556a501fcede6e0c50349191c"
|
||||
dependencies = [
|
||||
"libc",
|
||||
"windows-sys 0.52.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "stability"
|
||||
version = "0.2.1"
|
||||
@ -1045,36 +835,6 @@ version = "0.4.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3369f5ac52d5eb6ab48c6b4ffdc8efbcad6b89c765749064ba298f2c68a16a76"
|
||||
|
||||
[[package]]
|
||||
name = "tokio"
|
||||
version = "1.38.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ba4f4a02a7a80d6f274636f0aa95c7e383b912d41fe721a31f29e29698585a4a"
|
||||
dependencies = [
|
||||
"backtrace",
|
||||
"bytes",
|
||||
"libc",
|
||||
"mio",
|
||||
"num_cpus",
|
||||
"parking_lot",
|
||||
"pin-project-lite",
|
||||
"signal-hook-registry",
|
||||
"socket2",
|
||||
"tokio-macros",
|
||||
"windows-sys 0.48.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tokio-macros"
|
||||
version = "2.3.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5f5ae998a069d4b5aba8ee9dad856af7d520c3699e6159b185c2acd48155d39a"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "toml_datetime"
|
||||
version = "0.6.6"
|
||||
|
||||
@ -48,9 +48,6 @@ include = [
|
||||
[dependencies]
|
||||
anyhow = "1.0.86"
|
||||
|
||||
tokio = { version = "1.0", features = ["full"] }
|
||||
futures = "0.3"
|
||||
|
||||
clap = { version = "4.5.9", features = ["derive"] }
|
||||
crossterm = "0.27.0"
|
||||
hashbrown = "0.14.5"
|
||||
|
||||
@ -192,8 +192,6 @@ bin = [
|
||||
{ name = "async1_sol", path = "../solutions/24_async/async1.rs" },
|
||||
{ name = "async2", path = "../exercises/24_async/async2.rs" },
|
||||
{ name = "async2_sol", path = "../solutions/24_async/async2.rs" },
|
||||
{ name = "async3", path = "../exercises/24_async/async3.rs" },
|
||||
{ name = "async3_sol", path = "../solutions/24_async/async3.rs" },
|
||||
]
|
||||
|
||||
[package]
|
||||
|
||||
@ -18,4 +18,3 @@ Navigate the complexities of error handling in async code. Understand how errors
|
||||
|
||||
- [Learn more about async programming in Rust](https://doc.rust-lang.org/book/ch16-00-concurrency.html)
|
||||
- [Deep dive into handling concurrency](https://doc.rust-lang.org/book/ch16-02-message-passing.html)
|
||||
- [Advanced async patterns](https://tokio.rs/tokio/tutorial)
|
||||
|
||||
@ -1,30 +1,22 @@
|
||||
// This program creates multiple asynchronous tasks that each simulate a long-running operation
|
||||
// using `async` and `await`. Each task will return how much time it took to complete.
|
||||
// The program should wait until all the tasks have finished and should collect their return values into a vector.
|
||||
|
||||
use async_std::task;
|
||||
use std::time::{Duration, Instant};
|
||||
use tokio::time::{sleep, Duration};
|
||||
|
||||
async fn perform_task(id: usize) -> u128 {
|
||||
async fn run_async_task(id: usize) -> u128 {
|
||||
let start = Instant::now();
|
||||
// Simulate async work using sleep
|
||||
tokio::time::sleep(Duration::from_millis(250)).await;
|
||||
// TODO: Replace the synchronous sleep with an asynchronous sleep.
|
||||
task::sleep(Duration::from_millis(250)).await;
|
||||
println!("Task {id} done");
|
||||
start.elapsed().as_millis()
|
||||
}
|
||||
|
||||
async fn main_async() {
|
||||
let mut handles = Vec::new();
|
||||
async fn main() {
|
||||
let mut tasks = Vec::new();
|
||||
|
||||
for i in 0..10 {
|
||||
let handle = perform_task(i);
|
||||
handles.push(handle);
|
||||
// TODO: Push new asynchronous tasks into the vector.
|
||||
}
|
||||
|
||||
let mut results = Vec::new();
|
||||
for handle in handles {
|
||||
// TODO: Use `.await` to collect the results of all tasks into the `results` vector.
|
||||
// Remember to handle each async task using the appropriate syntax for awaiting.
|
||||
}
|
||||
// TODO: Wait for all tasks to complete and collect their results.
|
||||
|
||||
if results.len() != 10 {
|
||||
panic!("Oh no! Some task isn't done yet!");
|
||||
@ -36,6 +28,7 @@ async fn main_async() {
|
||||
}
|
||||
}
|
||||
|
||||
// Main function that starts the async main function using `task::block_on`.
|
||||
fn main() {
|
||||
block_on(main_async());
|
||||
task::block_on(main());
|
||||
}
|
||||
|
||||
@ -1,31 +1,60 @@
|
||||
// This program demonstrates the transformation of a synchronous function into an asynchronous one.
|
||||
// The original function performs a time-consuming operation, which we'll simulate with a sleep.
|
||||
// You need to convert this function to use async/await syntax and understand how it improves the responsiveness of the application.
|
||||
use async_std::task;
|
||||
use std::time::{Duration, Instant};
|
||||
use std::fmt;
|
||||
|
||||
use std::time::Duration;
|
||||
use futures::executor::block_on; // This is for running the async main function in this educational context.
|
||||
|
||||
// Synchronous version of a function that simulates a long-running operation
|
||||
fn calculate_value_synchronously() -> i32 {
|
||||
println!("Starting synchronous calculation...");
|
||||
std::thread::sleep(Duration::from_secs(2)); // Simulating a long-running task
|
||||
println!("Synchronous calculation done.");
|
||||
42 // returns a computed value
|
||||
#[derive(Debug)]
|
||||
enum TaskError {
|
||||
Timeout,
|
||||
Other(String),
|
||||
}
|
||||
|
||||
// TODO: Convert this function to async version
|
||||
async fn calculate_value_asynchronously() -> i32 {
|
||||
|
||||
impl fmt::Display for TaskError {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
match *self {
|
||||
TaskError::Timeout => write!(f, "Task timed out"),
|
||||
TaskError::Other(ref err) => write!(f, "Other error: {}", err),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
async fn main_async() {
|
||||
println!("Calling synchronous function:");
|
||||
let sync_result = calculate_value_synchronously();
|
||||
println!("Result from synchronous function: {}", sync_result);
|
||||
// TODO: Define an asynchronous function that may return an error.
|
||||
async fn run_async_task(id: usize) -> Result<u128, TaskError> {
|
||||
let start = Instant::now();
|
||||
// Simulate a possible failure
|
||||
if id == 5 {
|
||||
// Simulate a timeout error
|
||||
task::sleep(Duration::from_millis(100)).await;
|
||||
return Err(TaskError::Timeout);
|
||||
} else if id == 8 {
|
||||
// Simulate another type of error
|
||||
return Err(TaskError::Other("Unexpected error".to_string()));
|
||||
}
|
||||
|
||||
// TODO: Call the async function here and print its result
|
||||
// Normal operation with async sleep
|
||||
task::sleep(Duration::from_millis(250)).await;
|
||||
println!("Task {id} done");
|
||||
Ok(start.elapsed().as_millis())
|
||||
}
|
||||
|
||||
async fn main() {
|
||||
let mut tasks = Vec::new();
|
||||
|
||||
// TODO: Create and store asynchronous tasks in the `tasks` vector.
|
||||
for i in 0..10 {
|
||||
tasks.push(run_async_task(i)); }
|
||||
|
||||
// TODO: Wait for all tasks to complete and collect their results, handling errors appropriately.
|
||||
|
||||
// Process results
|
||||
for (i, result) in results.into_iter().enumerate() {
|
||||
match result {
|
||||
Ok(duration) => println!("Task {i} took {duration}ms"),
|
||||
Err(e) => println!("Task {i} failed with error: {}", e),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Main function that starts the async main function using `task::block_on`.
|
||||
fn main() {
|
||||
block_on(main_async());
|
||||
task::block_on(main());
|
||||
}
|
||||
|
||||
@ -1,40 +0,0 @@
|
||||
// This program demonstrates error handling in asynchronous Rust code. We will simulate a function that can fail,
|
||||
// and you will handle the error appropriately in an asynchronous context.
|
||||
|
||||
use std::time::Duration;
|
||||
use futures::executor::block_on; // For running the async main function in this educational context.
|
||||
use tokio; // We use tokio for the async functionality.
|
||||
use anyhow::{Result, anyhow}; // To simplify error handling
|
||||
|
||||
// Asynchronous function that might fail
|
||||
async fn might_fail(id: u32) -> Result<u32> {
|
||||
if id % 2 == 0 {
|
||||
tokio::time::sleep(Duration::from_millis(500)).await;
|
||||
Ok(id)
|
||||
} else {
|
||||
tokio::time::sleep(Duration::from_millis(500)).await;
|
||||
Err(anyhow!("Failed on odd id"))
|
||||
}
|
||||
}
|
||||
|
||||
async fn main_async() {
|
||||
let ids = [1, 2, 3, 4, 5];
|
||||
let mut results = Vec::new();
|
||||
|
||||
for id in ids {
|
||||
// TODO: Handle the potential error here using appropriate async error handling methods.
|
||||
// Consider using match or Result combinators like `map_err` or `and_then`.
|
||||
}
|
||||
|
||||
// Display results
|
||||
for result in results {
|
||||
match result {
|
||||
Ok(num) => println!("Processed number: {}", num),
|
||||
Err(e) => println!("Error occurred: {}", e),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn main() {
|
||||
block_on(main_async());
|
||||
}
|
||||
@ -1209,16 +1209,10 @@ Add `AsRef<str>` or `AsMut<u32>` as a trait bound to the functions."""
|
||||
name = "async1"
|
||||
dir = "24_async"
|
||||
hint = """
|
||||
Use `.await` to collect the results of all tasks into the `results` vector."""
|
||||
Push new asynchronous tasks into the vector."""
|
||||
|
||||
[[exercises]]
|
||||
name = "async2"
|
||||
dir = "24_async"
|
||||
hint = """
|
||||
Synchronous version of a function that simulates a long-running operation"""
|
||||
|
||||
[[exercises]]
|
||||
name = "async3"
|
||||
dir = "24_async"
|
||||
hint = """
|
||||
Consider using match or Result combinators like `map_err` or `and_then`."""
|
||||
Wait for all tasks to complete and collect their results, handling errors appropriately."""
|
||||
|
||||
@ -1,30 +1,25 @@
|
||||
// This program creates multiple asynchronous tasks that each simulate a long-running operation
|
||||
// using `async` and `await`, and each task will return how much time it took to complete.
|
||||
// The program should wait until all the tasks have finished and should collect their return values into a vector.
|
||||
|
||||
// Importing necessary modules from async-std to handle asynchronous tasks.
|
||||
use async_std::task;
|
||||
use std::time::{Duration, Instant};
|
||||
use tokio::time::{sleep, Duration};
|
||||
|
||||
async fn perform_task(id: usize) -> u128 {
|
||||
async fn run_async_task(id: usize) -> u128 {
|
||||
let start = Instant::now();
|
||||
// Simulate async work using sleep
|
||||
tokio::time::sleep(Duration::from_millis(250)).await;
|
||||
// Simulate work by sleeping, but now this is asynchronous sleep.
|
||||
task::sleep(Duration::from_millis(250)).await;
|
||||
println!("Task {id} done");
|
||||
start.elapsed().as_millis()
|
||||
}
|
||||
|
||||
async fn main_async() {
|
||||
let mut handles = Vec::new();
|
||||
async fn main() {
|
||||
let mut tasks = Vec::new();
|
||||
|
||||
// Create asynchronous tasks
|
||||
for i in 0..10 {
|
||||
let handle = perform_task(i);
|
||||
handles.push(handle);
|
||||
tasks.push(run_async_task(i));
|
||||
}
|
||||
|
||||
let mut results = Vec::new();
|
||||
for handle in handles {
|
||||
// Use `.await` to collect the results of all tasks into the `results` vector.
|
||||
results.push(handle.await);
|
||||
}
|
||||
// Wait for all tasks to complete and collect their results.
|
||||
let results = futures::future::join_all(tasks).await;
|
||||
|
||||
if results.len() != 10 {
|
||||
panic!("Oh no! Some task isn't done yet!");
|
||||
@ -36,7 +31,7 @@ async fn main_async() {
|
||||
}
|
||||
}
|
||||
|
||||
#[tokio::main]
|
||||
async fn main() {
|
||||
main_async().await;
|
||||
}
|
||||
// Main function now starts the async main function using `task::block_on`.
|
||||
fn main() {
|
||||
task::block_on(main());
|
||||
}
|
||||
|
||||
@ -1,37 +1,60 @@
|
||||
// This program demonstrates the transformation of a synchronous function into an asynchronous one.
|
||||
// The original function performs a time-consuming operation, which we'll simulate with a sleep.
|
||||
// You need to convert this function to use async/await syntax and understand how it improves the responsiveness of the application.
|
||||
use async_std::task;
|
||||
use std::time::{Duration, Instant};
|
||||
use std::fmt;
|
||||
|
||||
use std::time::Duration;
|
||||
use futures::executor::block_on; // This is for running the async main function in this educational context.
|
||||
use tokio; // We use tokio for the async sleep functionality.
|
||||
|
||||
// Synchronous version of a function that simulates a long-running operation
|
||||
fn calculate_value_synchronously() -> i32 {
|
||||
println!("Starting synchronous calculation...");
|
||||
std::thread::sleep(Duration::from_secs(2)); // Simulating a long-running task
|
||||
println!("Synchronous calculation done.");
|
||||
42 // returns a computed value
|
||||
// 自定义错误类型
|
||||
#[derive(Debug)]
|
||||
enum TaskError {
|
||||
Timeout,
|
||||
Other(String),
|
||||
}
|
||||
|
||||
// Converted to async version
|
||||
async fn calculate_value_asynchronously() -> i32 {
|
||||
println!("Starting asynchronous calculation...");
|
||||
tokio::time::sleep(Duration::from_secs(2)).await; // Using Tokio's async sleep
|
||||
println!("Asynchronous calculation done.");
|
||||
42 // returns a computed value
|
||||
impl fmt::Display for TaskError {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
match *self {
|
||||
TaskError::Timeout => write!(f, "Task timed out"),
|
||||
TaskError::Other(ref err) => write!(f, "Other error: {}", err),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
async fn main_async() {
|
||||
println!("Calling synchronous function:");
|
||||
let sync_result = calculate_value_synchronously();
|
||||
println!("Result from synchronous function: {}", sync_result);
|
||||
async fn run_async_task(id: usize) -> Result<u128, TaskError> {
|
||||
let start = Instant::now();
|
||||
// Simulate a possible failure
|
||||
if id == 5 {
|
||||
// Simulate a timeout error
|
||||
task::sleep(Duration::from_millis(100)).await;
|
||||
return Err(TaskError::Timeout);
|
||||
} else if id == 8 {
|
||||
// Simulate another type of error
|
||||
return Err(TaskError::Other("Unexpected error".to_string()));
|
||||
}
|
||||
|
||||
println!("Calling asynchronous function:");
|
||||
let async_result = calculate_value_asynchronously().await;
|
||||
println!("Result from asynchronous function: {}", async_result);
|
||||
// Normal operation with async sleep
|
||||
task::sleep(Duration::from_millis(250)).await;
|
||||
println!("Task {id} done");
|
||||
Ok(start.elapsed().as_millis())
|
||||
}
|
||||
|
||||
async fn main() {
|
||||
let mut tasks = Vec::new();
|
||||
|
||||
for i in 0..10 {
|
||||
tasks.push(run_async_task(i));
|
||||
}
|
||||
|
||||
let results: Vec<Result<u128, TaskError>> = futures::future::join_all(tasks).await;
|
||||
|
||||
// Process results
|
||||
for (i, result) in results.into_iter().enumerate() {
|
||||
match result {
|
||||
Ok(duration) => println!("Task {i} took {duration}ms"),
|
||||
Err(e) => println!("Task {i} failed with error: {}", e),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Main function that starts the async main function using `task::block_on`.
|
||||
fn main() {
|
||||
block_on(main_async());
|
||||
task::block_on(main());
|
||||
}
|
||||
|
||||
@ -1,43 +0,0 @@
|
||||
// This program demonstrates error handling in asynchronous Rust code. We simulate a function that can fail,
|
||||
// and handle the error appropriately in an asynchronous context.
|
||||
|
||||
use std::time::Duration;
|
||||
use futures::executor::block_on; // For running the async main function in this educational context.
|
||||
use tokio; // We use tokio for the async functionality.
|
||||
use anyhow::{Result, anyhow}; // To simplify error handling
|
||||
|
||||
// Asynchronous function that might fail
|
||||
async fn might_fail(id: u32) -> Result<u32> {
|
||||
if id % 2 == 0 {
|
||||
tokio::time::sleep(Duration::from_millis(500)).await;
|
||||
Ok(id)
|
||||
} else {
|
||||
tokio::time::sleep(Duration::from_millis(500)).await;
|
||||
Err(anyhow!("Failed on odd id"))
|
||||
}
|
||||
}
|
||||
|
||||
async fn main_async() {
|
||||
let ids = [1, 2, 3, 4, 5];
|
||||
let mut results = Vec::new();
|
||||
|
||||
for id in ids {
|
||||
let result = might_fail(id).await;
|
||||
match result {
|
||||
Ok(num) => results.push(Ok(num)),
|
||||
Err(e) => results.push(Err(e)),
|
||||
}
|
||||
}
|
||||
|
||||
// Display results
|
||||
for result in results {
|
||||
match result {
|
||||
Ok(num) => println!("Processed number: {}", num),
|
||||
Err(e) => println!("Error occurred: {}", e),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn main() {
|
||||
block_on(main_async());
|
||||
}
|
||||
Loading…
x
Reference in New Issue
Block a user