pointers/ref

For pointers, a distinction needs to be made between destructuring
and dereferencing as they are different concepts which are used
differently from a language like C.

  • Dereferencing uses *
  • Destructuring uses &, ref, and ref mut
  1. fn main() {
  2. // Assign a reference of type `i32`. The `&` signifies there
  3. // is a reference being assigned.
  4. let reference = &4;
  5. match reference {
  6. // If `reference`s is pattern matched against `&val`, it results
  7. // in a comparison like:
  8. // `&i32`
  9. // `&val`
  10. // ^ We see that if the matching `&`s are dropped, then the `i32`
  11. // should be assigned to `val`.
  12. &val => println!("Got a value via destructuring: {:?}", val),
  13. }
  14. // To avoid the `&`, you dereference before matching.
  15. match *reference {
  16. val => println!("Got a value via dereferencing: {:?}", val),
  17. }
  18. // What if you don't start with a reference? `reference` was a `&`
  19. // because the right side was already a reference. This is not
  20. // a reference because the right side is not one.
  21. let _not_a_reference = 3;
  22. // Rust provides `ref` for exactly this purpose. It modifies the
  23. // assignment so that a reference is created for the element; this
  24. // reference is assigned.
  25. let ref _is_a_reference = 3;
  26. // Accordingly, by defining 2 values without references, references
  27. // can be retrieved via `ref` and `ref mut`.
  28. let value = 5;
  29. let mut mut_value = 6;
  30. // Use `ref` keyword to create a reference.
  31. match value {
  32. ref r => println!("Got a reference to a value: {:?}", r),
  33. }
  34. // Use `ref mut` similarly.
  35. match mut_value {
  36. ref mut m => {
  37. // Got a reference. Gotta dereference it before we can
  38. // add anything to it.
  39. *m += 10;
  40. println!("We added 10. `mut_value`: {:?}", m);
  41. },
  42. }
  43. }