在移动结构后,我对结构成员的引用如何仍然有效?

How is my reference to a struct member still valid after the struct was moved?

我正在使用一个函数(名为 get)创建对结构成员的引用,然后我使用另一个函数(名为 pr)移动该结构,然后取消引用之前创建的指针。

我是不是错了(a.k.a。无意中工作),还是我的参考根据某些规则仍然有效?

struct MyStruct {
    inner: i32,
}

fn get(a: &MyStruct) -> &i32 {
    return &a.inner;
}

fn pr(a: MyStruct) {
    println!("MyStruct {}", a.inner);
}

fn main() {
    println!("Hello, world!");
    let x = MyStruct { inner: 3 };
    let &i = get(&x);
    pr(x);
    println!("i {}", i);
}

Rust playground 输出:

Hello, world!
MyStruct 3
i 3

let 表达式得到模式匹配并且

let &i = get(&x); // i.e. a &i32

导致 i 被分配给 i32,并且由于 i32 是可复制的,因此不存在所有权冲突。

Rust 参考指出 "a let statement introduces a new set of variables, given by a pattern" (source) and "patterns consist of some combination of literals, destructured arrays or enum constructors, structs and tuples, variable binding specifications" (source).

绑定的左侧 &i 不仅仅是一个文字,它告诉编译器它应该尝试对右侧表达式进行模式匹配。在这种情况下,它导致 i 指向可复制值 (i32) 而不是引用 (&i32)。换句话说:

let &i = get(&x);

相当于

let i = *get(&x);

所以x没有借用,pr(x)仍然适用