簡體   English   中英

為什么在 rust 中移動閉包不能移動引用變量的所有權?

[英]Why move closure in rust can't move the ownership of a referenced variable?

這是示例

fn call_with_f<F>(f:F) where F: FnOnce(){
    f();
}
struct Vec2{
    x:i32,
    y:i32
}
impl Vec2{
    fn new(x:i32, y:i32) -> Self{
        Self{
            x,
            y
        }
    }
    fn x(&self) -> &i32{
        &self.x
    }
}
fn main() {
    let v = Vec2::new(1,2);
    let rx = v.x();
    call_with_f(move||{
        println!("{}", v.x());
        println!("{}", rx);
    });
}

編譯器給出

error[E0505]: cannot move out of `v` because it is borrowed
  --> src\main.rs:88:14
   |
87 |     let rx = v.x();
   |              - borrow of `v` occurs here
88 |     call_with_f(move||{
   |                 ^^^^^^ move out of `v` occurs here
89 |         println!("{}", v.x());
   |                        - move occurs due to use in closure
90 |         println!("{}", rx);
   |                        -- borrow later captured here by closure

我知道編譯器的抱怨,但這種情況有時是必要的。 在一個非常復雜的
在這種情況下,在給閉包之前需要做很多工作,作為中間變量的引用可以簡化准備工作。 vrv在開始時具有相同的生命周期,根據移動閉包的語義,它們在移動后也保持相同的生命周期。 為什么?

您不能移動借入的值。 時期。

此外,這樣的閉包不能(安全地)存在:它需要存儲擁有的值和對它(部分)的引用,即它是自引用的 請參閱閉包中引用的生命周期

根據您的用例,可能有各種解決方案,從最好到最差排序:

  • 在閉包內創建引用。
  • 不要移動擁有的價值。 人們提出問題的常見原因之一是因為他們需要線程的'static閉包”。 如果是這種情況,您可能會發現作用域線程很有幫助。
  • 使用諸如owning_ref (unsound!) 或ourboros (no known sound hole IIRC) 之類的 crate 來創建自引用閉包。 您可能需要手動(至少部分地)對關閉進行脫糖。
  • 使用unsafe的代碼來創建自引用閉包。 警告:除非您真的知道自己在做什么,否則不要這樣做。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM