foo: &Foo
is a reference to a Foo
, while foo: Foo
is a Foo
value.
The first signature declares that the function only borrows foo
by taking a reference, the second signature declares that it takes ownership of the value.
Although both compile, and both are correct, there is a difference in how you call them and what you can do in the function body.
First variant:
bar(&foo)
// foo is still available here
Second variant:
bar(foo)
// foo is no longer available here; it was moved into bar
// (unless foo is Copy, in which case it is copied into bar)
Furthermore, if the function bar
owns the value foo
, it is possible to move fields out of foo. This is not possible if foo
is a reference.
Here is a demonstration with a field type that is not Copy
:
struct Foo {
x: String,
}
fn bar1(foo: &Foo) -> &String {
// let y = foo.x; // moving out of a reference would not compile
&foo.x // can return a reference to field
}
fn bar2(foo: Foo) -> String {
foo.x // can move x out of foo
}
fn main() {
let foo = Foo {
x: "foo".to_string(),
};
let x: &String = bar1(&foo);
let x: String = bar2(foo);
// bar1(&foo); // would not compile; foo has been moved into bar2 above
}
2
solved What is the point of & in Rust if I can omit it?