Rust 为什么将移动值的成员指定给时编译不会失败?

Rust 为什么将移动值的成员指定给时编译不会失败?,rust,Rust,我正在研究中的例子 我得到这个错误(Rust 1.25.0): 错误[E0382]:使用移动值:`point.x` -->src/main.rs:23:26 | 19 | p2:点, |----值移到了这里 ... 23 | println!(“x是{}”,第x点); |^^^^^^^^移动后此处使用的值 | =注意:之所以发生移动,是因为'point'具有'point'类型,而该类型不实现'Copy'特性 我知道我给了矩形对象点,这就是为什么我不能再访问它,但为什么编译在println上失败

我正在研究中的例子

我得到这个错误(Rust 1.25.0):

错误[E0382]:使用移动值:`point.x`
-->src/main.rs:23:26
|
19 | p2:点,
|----值移到了这里
...
23 | println!(“x是{}”,第x点);
|^^^^^^^^移动后此处使用的值
|
=注意:之所以发生移动,是因为'point'具有'point'类型,而该类型不实现'Copy'特性
我知道我给了
矩形
对象
,这就是为什么我不能再访问它,但为什么编译在
println上失败了而不是上一行的作业?

到底发生了什么

fn main() {
    let mut point: Point = Point { x: 0.3, y: 0.4 };
    println!("point coordinates: ({}, {})", point.x, point.y);

    drop(point);

    {
        let mut point: Point;
        point.x = 0.5;
    }

    println!(" x is {}", point.x);
}

事实证明,它已经被称为。

问题是编译器允许对结构进行部分重新初始化,但此后整个结构将无法使用。即使结构只包含一个字段,或者仅尝试读取刚重新初始化的字段,也会发生这种情况

struct Test {
    f: u32,
}

fn main() {
    let mut t = Test { f: 0 };
    let t1 = t;
    t.f = 1;
    println!("{}", t.f);
}

这在

中进行了讨论。我想“使用移动值”可以解释为您尝试读取其值的点。仅当您尝试使用移动的值时,从“技术”意义上讲,分配给它并不会真正改变生锈的保证。也就是说,我自己对其中的大部分都不太了解,所以我很想听听那些对此有更多了解的人的意见。感觉像是编译器的bug。更有趣的是,
让p2=point;点x=0.5;普林顿!(“x是{}”,p2.x)编译精细并打印0.3,因此
point.x=0.5可以nothng@qthree这是完全可以预料的;Rust使用值类型,而不是引用类型。为什么嵌套块中有另一个
let mut point
?这是否改变了问题,因为您分配给的点是一个新点,位于内存中与被删除的点不同的位置?@AlexKnauth我认为这样做的目的是指出编译器看到的情况。也就是说,编译器通过自己的允许赋值的“点”看到了额外的作用域对移动的值不做任何处理,但尝试初始化新值。但在原始代码中,该范围不存在,并且它没有创建新的
变量,而是分配给已删除的旧
。还是我误解了它的工作原理?@AlexKnauth你是对的,因为它不在原始代码中。我认为qthree在这里的意图是显示编译器看到的内容。。编译器将OP的代码视为存在这个额外的作用域。这就是为什么赋值有效,但是
println行没有。除了@Shepmaster,我不清楚这个答案提供了什么。它删除了错误的部分。作为奖励,我添加了一个关于这个问题的简要解释,因为仅仅发布一个链接是不好的形式。
struct Test {
    f: u32,
}

fn main() {
    let mut t = Test { f: 0 };
    let t1 = t;
    t.f = 1;
    println!("{}", t.f);
}