gpt4 book ai didi

asynchronous - 即使范围拥有变量的所有权,引用仍被保留而无法使用

转载 作者:行者123 更新时间:2023-12-03 11:41:59 24 4
gpt4 key购买 nike

我有一些看起来像这样的代码:

async move {
let res = do_sth(&state).await;
(state, res)
}.boxed()

(完整示例: https://gitlab.com/msrd0/async-issue)

我会说 async move block 拥有 state的所有权并传递 state 的引用沿着 do_sth方法,它是 async fn .但是,编译器也会保留 &state横跨 await绑定(bind),我不知道为什么会这样做:

error: future cannot be sent between threads safely
--> src/main.rs:30:5
|
30 | }.boxed()
| ^^^^^ future returned by `read_all` is not `Send`
|
= help: the trait `std::marker::Sync` is not implemented for `(dyn std::any::Any + std::marker::Send + 'static)`
note: future is not `Send` as this value is used across an await
--> src/main.rs:28:14
|
28 | let res = do_sth(&state).await;
| ^^^^^^^------^^^^^^^- `&state` is later dropped here
| | |
| | has type `&gotham::state::State`
| await occurs here, with `&state` maybe used later


我试着把 do_sth不带 await 的电话进入它自己的 block ,但这并没有解决错误。

有没有办法避免这个错误?

最佳答案

该错误显然与所有权或生命周期无关:

error: future cannot be sent between threads safely
gotham_restful::State没有实现 Sync trait,这意味着它的引用 &state不是线程安全的。但是,您将该引用传递给异步函数,然后等待该函数,Rust 编译器会自动推断该函数不是线程安全的,因此整个 block 变得“不是线程安全的”。 read_all 的返回值方法有 + Send但是,约束要求返回的 future 是线程安全的,因此这会导致错误。

一种可能的解决方案是重写 do_sth成为返回 future 的常规函数​​。这样,您可以确保从该函数返回的 future 实现 Send并且是线程安全的,而不是依赖编译器来推断它在哪里是线程安全的:

fn do_sth(_state: &State) -> impl Future<Output = NoContent> + Send {
// require that the future of this function is thread-safe ---^

async move {
Default::default()
}
}

请注意,这实际上不允许您执行任何非线程安全的操作,但它会指示编译器 do_sth函数应该是线程安全的,而不是试图手动推断它是否应该是线程安全的。

关于asynchronous - 即使范围拥有变量的所有权,引用仍被保留而无法使用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61291194/

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