代码之家  ›  专栏  ›  技术社区  ›  Mickael B.

有没有一种方法可以告诉编译器我正在管理循环中变量的所有权?

  •  1
  • Mickael B.  · 技术社区  · 6 年前

    我试图给循环中的一个函数一个变量的所有权,我有自己的布尔值来确保它只发生一次,但是编译器告诉我值在前一次迭代中被移动了。

    下面是一个例子:

    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
    

    有没有办法告诉编译器“没事,我来处理”?我不想使用参考资料( & )

    1 回复  |  直到 6 年前
        1
  •  6
  •   trent oli_obk    6 年前

    通常告诉编译器“没问题,我会处理它”的方法是使用 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 ,所以编译器不能确定 你好 只移动一次。 选择权 在那里编码不变量 可以 在这里是一件事,或者它可能“进入”类型,所以编译器可以知道 take_ownership 只有当有东西要传递给它时才调用。

    .take() 是一种替换 具有 None ,返回内容(如果有)。因为此方法不使用 选择权 ,可以在循环中多次调用它。 Cannot move out of borrowed content when trying to transfer ownership 是一个相关的问题。