gpt4 book ai didi

rust - 使用线程和async/await时如何解决 "cannot return value referencing local data"?

转载 作者:行者123 更新时间:2023-12-03 11:28:19 25 4
gpt4 key购买 nike

我正在学习 Rust,尤其是多线程和并行异步请求。

我阅读了文档,但仍然不明白我在哪里犯了错误。我假设我知道在哪里,但不知道如何解决它。

main.rs

use std::thread;

struct Request {
url: String,
}

impl Request {
fn new(name: &str) -> Request {
Request {
url: name.to_string(),
}
}

async fn call(&self, x: &str) -> Result<(), Box<dyn std::error::Error>> {
let resp = reqwest::get(x).await;
Ok(())
}
}

#[tokio::main]
async fn main() {
let requests = vec![
Request::new("https://www.google.com/"),
Request::new("https://www.google.com/"),
];
let handles: Vec<_> = requests
.into_iter()
.map(|request| {
thread::spawn(move || async {
request.call(&request.url).await;
})
})
.collect();

for y in handles {
println!("{:?}", y);
}
}
error[E0515]: cannot return value referencing local data `request`
--> src/main.rs:29:35
|
29 | thread::spawn(move || async {
| ___________________________________^
30 | | request.call(&request.url).await;
| | ------- `request` is borrowed here
31 | | })
| |_____________^ returns a value referencing data owned by the current function

Cargo.toml

[dependencies]
reqwest = "0.10.4"
tokio = { version = "0.2", features = ["full"] }

最佳答案

像闭包一样,async block 尽可能弱地捕获它们的变量。按优先顺序:

  1. 不可变引用
  2. 可变引用
  3. 按值(value)

这取决于变量在闭包/异步 block 中的使用方式。在您的示例中,request 仅通过引用使用,因此它仅通过引用捕获:

async {
request.call(&request.url).await;
}

但是,您需要将变量的所有权转移到异步 block ,以便在最终执行 future 时变量仍然存在。与闭包一样,这是通过 move 关键字完成的:

thread::spawn(move || async move {
request.call(&request.url).await;
})

另见:


在您的理解中,极不可能此时您想混合使用线程和异步。一种本质上是阻塞的,另一种期望代码不会阻塞。您应该遵循 How can I perform parallel asynchronous HTTP GET requests with reqwest? 中概述的示例相反。

另见:

关于rust - 使用线程和async/await时如何解决 "cannot return value referencing local data"?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60937839/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com