【问题标题】:Is there a way to tell the compiler that I am managing ownership of a variable in a loop?有没有办法告诉编译器我正在循环管理变量的所有权?
【发布时间】:2018-07-28 14:35:35
【问题描述】:

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

这是一个例子:

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

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

【问题讨论】:

    标签: loops rust ownership


    【解决方案1】:

    告诉编译器“没关系,我会处理它”的通常方式是使用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和hello之间没有类型级别的关系,所以编译器不能确定hello只被移动了一次。 Option 将不变的“这里可能有东西,或者它可能已经消失”编码到类型中,因此编译器可以知道 take_ownership 仅在有东西要传递给时才被调用它。

    .take() 是一种将a 替换为None 的方法,返回内容(如果有)。因为这个方法不消耗Option,所以循环调用多次就可以了。 Cannot move out of borrowed content when trying to transfer ownership 是一个相关问题。

    【讨论】:

      猜你喜欢
      • 2010-09-09
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-12-29
      • 1970-01-01
      • 2023-03-04
      • 2010-12-01
      相关资源
      最近更新 更多