首页 > 解决方案 > 有没有办法告诉编译器我正在循环管理变量的所有权?

问题描述

我试图将变量的所有权赋予循环中的函数,并且我有自己的布尔值以确保它只发生一次,但是编译器告诉我该值在上一次迭代中被移动。

这是一个例子:

fn take_ownership(a: String) {
    println!("{}", a);
}

fn main() {
    let mut a = true;
    let hello = "Hello".to_string();

    for _ in 0..5 {
        if a {
            a = false;
            take_ownership(hello);
        }
    }
}

使用此代码,编译器会告诉我:

error[E0382]: use of moved value: `hello`
  --> src/main.rs:12:28
   |
12 |             take_ownership(hello);
   |                            ^^^^^ value moved here in previous iteration of loop

有没有办法告诉编译器“没关系,我会处理它”?我不想使用引用(&)。

标签: loopsrustownership

解决方案


告诉编译器“没关系,我会处理它”的常用方法是使用unsafe. 你可以在这里使用unsafe一些深奥的ptr魔法,但这会非常脆弱并且很难证明是正确的。

然而,这是一个安全且简单的事情Option

let mut a = Some("Hello".to_string());

for _ in 0..5 {
    if let Some(hello) = a.take() {
        take_ownership(hello);
    }
}

a在原始版本中, and之间没有类型级别的关系hello,因此编译器无法确定hello它只移动了一次。Option将不变的“这里可能有东西,或者它可能已经消失”编码到类型中,因此编译器可以知道take_ownership只有在有东西要传递给它时才调用它。

.take()是一个用 替换的方法aNone返回内容(如果有的话)。因为这个方法不消耗Option,所以可以循环调用多次。尝试转移所有权时无法移出借用内容是一个相关问题。


推荐阅读