考虑以下人为设计的代码片段,请原谅它有点“长”:
use anyhow::{Ok, Result};
use std::sync::Arc;
use std::thread;
// a not-Copy struct
pub struct MoreNumbers {
third_num: u64,
fourth_num: u64,
}
pub async fn add_two_num_with_more_number(
num_one: u64,
num_two: u64,
more_nums: &MoreNumbers,
) -> Result<u64> {
check_num(num_one).await?; // calls another async function that returns a anyhow::Result<T>, where `T` is a different `T` from the return of the `add_two_num` function
check_num(num_two).await?;
anyhow::Ok(num_one + num_two + more_nums.third_num + more_nums.fourth_num)
}
pub async fn check_num(num: u64) -> Result<()> {
assert!(num <= u64::MAX /2, "There is a risk of overflow for adding two u64 numbers that are greater than half of u64::MAX");
Ok(())
}
#[tokio::main]
async fn main() -> anyhow::Result<()> {
let mut TRIES: u8 = 5;
let many_nums: Vec<u64> = vec![1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11];
let more_nums: MoreNumbers = MoreNumbers {
third_num: 12,
fourth_num: 13,
};
let more_nums_arc: Arc<MoreNumbers> = Arc::new(more_nums);
while TRIES > 1 {
thread::scope(|s| {
many_nums.chunks(2).map(|vector| {
let more_nums_arc_cloned: Arc<MoreNumbers> = Arc::clone(&more_nums_arc);
if let [first, second] = vector {
s.spawn(move || async move { // ------ >>>>> LOOK HERE! <<<<<
let result =
add_two_num_with_more_number(*first, *second, &more_nums_arc_cloned).await?;
anyhow::Ok(())
});
};
});
});
TRIES -= 1;
}
anyhow::Ok(())
}
以上代码编译:Playground.
我的问题与
move || async move {...}
行有关,让我们将第一个 move
命名为“移动一个”,将第二个 move
命名为“移动两个”,即 move (move-one) || aync move (move-two) {...}
.
当'move-two'被移除时,出现错误:
error[E0373]: async block may outlive the current function, but it borrows `more_nums_arc_cloned`, which is owned by the current function
--> src\main.rs:100:43
|
100 | s.spawn(move || async {
| ___________________________________________^
101 | | let result =
102 | | add_two_num_with_more_number(*first, *second, &more_nums_arc_cloned).await?;
| | -------------------- `more_nums_arc_cloned` is borrowed here
103 | | anyhow::Ok(())
104 | | });
| |_____________________^ may outlive borrowed value `more_nums_arc_cloned`
|
note: async block is returned here
--> src\main.rs:100:37
|
100 | s.spawn(move || async {
| _____________________________________^
101 | | let result =
102 | | add_two_num_with_more_number(*first, *second, &more_nums_arc_cloned).await?;
103 | | anyhow::Ok(())
104 | | });
| |_____________________^
help: to force the async block to take ownership of `more_nums_arc_cloned` (and any other referenced variables), use the `move` keyword
|
100 | s.spawn(move || async move {
| ++++
For more information about this error, try `rustc --explain E0373`.
当'移动一个'被删除时,同样(显示的错误是
second
但与first
相同):
error[E0373]: closure may outlive the current function, but it borrows `second`, which is owned by the current function
--> src\main.rs:100:29
|
96 | thread::scope(|s| {
| - lifetime `'1` appears in the type of `s`
...
100 | s.spawn(|| async move {
| ^^ may outlive borrowed value `second`
101 | let result =
102 | add_two_num_with_more_number(*first, *second, &more_nums_arc_cloned).await?;
| ------- `second` is borrowed here
|
note: function requires argument type to outlive `'1`
--> src\main.rs:100:21
|
100 | / s.spawn(|| async move {
101 | | let result =
102 | | add_two_num_with_more_number(*first, *second, &more_nums_arc_cloned).await?;
103 | | anyhow::Ok(())
104 | | });
| |______________________^
help: to force the closure to take ownership of `second` (and any other referenced variables), use the `move` keyword
|
100 | s.spawn(move || async move {
| ++++
简单地说:
first
和 second
移动到异步块中。&more_nums_arc_cloned
移动到异步块中。我的问题是:
我们如何判断哪个移动将哪个变量移动到哪个块?