移动结构体后更改其字段

3
我是一个有用的助手,可以翻译文本。
我对以下行为感到困惑:能否有人解释一下发生了什么?
考虑以下代码:
struct Point {
    cx : u32,
}
fn main() {
    let mut p1 = Point { cx: 100 };
    let     p2 = p1; 
    p1.cx      = 5000;
    // println!("p1.x = {}", p1.cx); // disallowed as p1.cx is "moved" ... ok
    println!("p2.x = {}", p2.cx); // ==> prints 100 (!)
}

具体来说,我感到困惑的是:

  1. 即使已经发生了移动p1.cx更新仍然被允许,
  2. p2.x返回的值实际上不是更新后的5000,而是旧的100

由于没有复制特性(因此进行了移动),我原本期望的是新值,所以预计只会打印一个单元格的更新值(5000)。

但是,我一定是漏掉了什么。有什么提示吗?谢谢!

1个回答

7

现在这是被禁止的。

以前是允许的。然而,这是旧借用检查器中的错误,随着新借用检查器(NLL)的引入,它已经被改为一个警告,然后是一个错误。

例如,在rustc 1.39.0和2015版中,您会收到以下警告:

warning[E0382]: assign to part of moved value: `p1`
 --> a.rs:8:5
  |
6 |     let mut p1 = Point { cx: 100 };
  |         ------ move occurs because `p1` has type `Point`, which does not implement the `Copy` trait
7 |     let p2 = p1;
  |              -- value moved here
8 |     p1.cx = 5000;
  |     ^^^^^^^^^^^^ value partially assigned here after move
  |
  = warning: this error has been downgraded to a warning for backwards compatibility with previous releases
  = warning: this represents potential undefined behavior in your code and this warning will become a hard error in the future
  = note: for more information, try `rustc --explain E0729`

rustc 1.40.0 将其转化为了一个错误:

error[E0382]: assign to part of moved value: `p1`
 --> src/main.rs:7:5
  |
5 |     let mut p1 = Point { cx: 100 };
  |         ------ move occurs because `p1` has type `Point`, which does not implement the `Copy` trait
6 |     let p2 = p1;
  |              -- value moved here
7 |     p1.cx = 5000;
  |     ^^^^^^^^^^^^ value partially assigned here after move

error: aborting due to previous error

注意,这也是2018年版长时间存在的错误(可能自版面创建以来就存在)。
另请参见:
- E0729代码描述">E0729代码描述 - 1.40版本 发布说明

如先前宣布的那样,2015版中的任何先前的NLL警告现在都是硬错误。


谢谢,现在更清楚了!我以为我已经有最新版本了,显然不是,我会更新的。 - Ranjit Jhala

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接