问题
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