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

孤者浪人 提交于 2019-12-07 23:03:46

问题


I'm creating a reference to a structure member using a function (named get), then I move the struct using another function (named pr), then I dereference the previously created pointer.

Am I in the wrong here (a.k.a. working by accident), or is my reference is still valid by some rule?

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);
}

The Rust playground outputs:

Hello, world!
MyStruct 3
i 3

回答1:


The let expression gets pattern-matched and

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

Results in i being assigned to i32 and since i32 is copyable, there is no ownership violation.

The Rust reference states that "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).

The left-hand side of the binding, &i is not just a literal, which tells the compiler that it should try to pattern-match against the right-hand side expression. In this case it results in i pointing to a copyable value (i32) and not a reference (&i32). In other words:

let &i = get(&x);

is equivalent to

let i = *get(&x);

So x is not borrowed and pr(x) is still applicable.



来源:https://stackoverflow.com/questions/39586277/how-is-my-reference-to-a-struct-member-still-valid-after-the-struct-was-moved

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!