如何指示 rust 将值移动到另一个范围?

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

以下代码无法编译,因为编译器认为

s
保留在
main
的范围内,而不是移入
spawn
的范围。为什么编译器不明白
s
不需要绑定到外部作用域并且可以移动到
spawn
的作用域?

struct MyStruct {}

impl MyStruct {
    async fn run(&self) {
        println!("Hello");
    }
}

#[tokio::main]
async fn main() {
    let s = MyStruct{};
    tokio::task::spawn(s.run());
}

main()

错误:

[E0597] Error: `s` does not live long enough
    ╭─[command_21:1:1]
    │
 11 │     let s = S{};
    ·         ┬  
    ·         ╰── binding `s` declared here
 12 │     tokio::task::spawn(s.run());
    ·                        ───┬───  
    ·                           ╰───── borrowed value does not live long enough
    ·                           │     
    ·                           ╰───── argument requires that `s` is borrowed for `'static`
 13 │ }
    · ┬  
    · ╰── `s` dropped here while still borrowed
────╯

我找到了一些解决方法,但很高兴听到是否有更好的方法:

如果我更改 fn 签名以移动 self 而不是借用:

run(self)  // removed the &.

或者,如果我无法更改签名,我可以在调用站点添加显式移动:

tokio::task::spawn(async move { s.run().await });

有更好的方法吗?

rust ownership
1个回答
0
投票

正如您提到的,显式

async move
块是最好的方法。

Future
返回的未命名
run
类型借用了
self
,但
tokio::task::spawn
需要一个
'static
未来(即不借用的未来)。您不能只是“将自己移至未来”,因为这需要
run
返回不同的类型。但是,您可以通过
async move
创建一个新的未来,其中包含
self
,并且只需调用
run

© www.soinside.com 2019 - 2024. All rights reserved.