指针和引用

对指针来说,解构(destructure)和解引用(dereference)要区分开,因为这两者的概念是不同的,和 C 那样的语言用法不一样。

  • 解引用使用 *
  • 解构使用 &ref、和 ref mut
  1. fn main() {
  2. // 获得一个 `i32` 类型的引用。`&` 表示取引用。
  3. let reference = &4;
  4. match reference {
  5. // 如果用 `&val` 这个模式去匹配 `reference`,就相当于做这样的比较:
  6. // `&i32`(译注:即 `reference` 的类型)
  7. // `&val`(译注:即用于匹配的模式)
  8. // ^ 我们看到,如果去掉匹配的 `&`,`i32` 应当赋给 `val`。
  9. // 译注:因此可用 `val` 表示被 `reference` 引用的值 4。
  10. &val => println!("Got a value via destructuring: {:?}", val),
  11. }
  12. // 如果不想用 `&`,需要在匹配前解引用。
  13. match *reference {
  14. val => println!("Got a value via dereferencing: {:?}", val),
  15. }
  16. // 如果一开始就不用引用,会怎样? `reference` 是一个 `&` 类型,因为赋值语句
  17. // 的右边已经是一个引用。但下面这个不是引用,因为右边不是。
  18. let _not_a_reference = 3;
  19. // Rust 对这种情况提供了 `ref`。它更改了赋值行为,从而可以对具体值创建引用。
  20. // 下面这行将得到一个引用。
  21. let ref _is_a_reference = 3;
  22. // 相应地,定义两个非引用的变量,通过 `ref` 和 `ref mut` 仍可取得其引用。
  23. let value = 5;
  24. let mut mut_value = 6;
  25. // 使用 `ref` 关键字来创建引用。
  26. // 译注:下面的 r 是 `&i32` 类型,它像 `i32` 一样可以直接打印,因此用法上
  27. // 似乎看不出什么区别。但读者可以把 `println!` 中的 `r` 改成 `*r`,仍然能
  28. // 正常运行。前面例子中的 `println!` 里就不能是 `*val`,因为不能对整数解
  29. // 引用。
  30. match value {
  31. ref r => println!("Got a reference to a value: {:?}", r),
  32. }
  33. // 类似地使用 `ref mut`。
  34. match mut_value {
  35. ref mut m => {
  36. // 已经获得了 `mut_value` 的引用,先要解引用,才能改变它的值。
  37. *m += 10;
  38. println!("We added 10. `mut_value`: {:?}", m);
  39. },
  40. }
  41. }

参见:

ref 模式