Rust Programming By Example
上QQ阅读APP看书,第一时间看更新

References

Let's try the following code, which would work in other programming languages:

let p1 = Point { x: 1, y: 2 };
let p2 = p1;
println!("{}", p1.x);

We can see that Rust doesn't accept this. It gives the following error:

error[E0382]: use of moved value: `p1.x`
 --> src/main.rs:4:20
  |
3 |     let p2 = p1;
  |         -- value moved here
4 |     println!("{}", p1.x);
  |                    ^^^^ value used here after move
  |
  = note: move occurs because `p1` has type `Point`, which does not implement the `Copy` trait

This means that we cannot use a value after it is moved. In Rust, values are moved by default instead of being copied, except in some cases, as we'll see in the next sub-section.

To avoid moving a value, we can take a reference to it by prefixing it with &:

let p1 = Point { x: 1, y: 2 };
let p2 = &p1;
println!("{}", p1.x);

This code compiles and, in this case, p2 is a reference to p1, which means that it points to the same memory location. Rust ensures that it is always safe to use a reference, since references are not pointers, they cannot be NULL.

References can also be used in the type of a function parameter. This is a function that prints a point, without moving the value:

fn print_point(point: &Point) {
    println!("x: {}, y: {}", point.x, point.y);
}

We can use it this way:

print_point(&p1);
println!("{}", p1.x);

We can still use the point after calling print_point, because we send a reference to the function instead of moving the point into the function.