`移动|| async move {...}`,如何知道哪个移动正在移动哪个?

问题描述 投票:0回答:0

考虑以下人为设计的代码片段,请原谅它有点“长”:

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 {
    |                             ++++

简单地说:

  1. 'move-one' 将
    first
    second
    移动到异步块中。
  2. 'move-two' 将
    &more_nums_arc_cloned
    移动到异步块中。

我的问题是:

我们如何判断哪个移动将哪个变量移动到哪个块?

rust async-await concurrency parallel-processing move
© www.soinside.com 2019 - 2024. All rights reserved.