• 方法

    方法

    方法是从属于对象的函数(Mathods are functions attached to objects)。这些方法通过
    关键字 self 来访问对象中的数据和其他方法。方法在 impl 代码块下定义。

    1. struct Point {
    2. x: f64,
    3. y: f64,
    4. }
    5. // 实现的代码块,所有的 `Point` 方法都在这里给出
    6. impl Point {
    7. // 这是一个静态方法(static method)
    8. // 静态方法不需要通过实例来调用
    9. // 这类方法一般用作构造器(constructor)
    10. fn origin() -> Point {
    11. Point { x: 0.0, y: 0.0 }
    12. }
    13. // 另外一个静态方法,带有两个参数:
    14. fn new(x: f64, y: f64) -> Point {
    15. Point { x: x, y: y }
    16. }
    17. }
    18. struct Rectangle {
    19. p1: Point,
    20. p2: Point,
    21. }
    22. impl Rectangle {
    23. // 这是实例方法(instance method)
    24. // `&self` 是 `self: &Self` 的语法糖(sugar),其中 `Self` 是所调用对象
    25. // 的类型。在这个例子中 `Self` = `Rectangle`
    26. fn area(&self) -> f64 {
    27. // `self` 通过点运算符来访问结构体字段
    28. let Point { x: x1, y: y1 } = self.p1;
    29. let Point { x: x2, y: y2 } = self.p2;
    30. // `abs` 是一个 `f64` 类型的方法,返回调用者的绝对值
    31. ((x1 - x2) * (y1 - y2)).abs()
    32. }
    33. fn perimeter(&self) -> f64 {
    34. let Point { x: x1, y: y1 } = self.p1;
    35. let Point { x: x2, y: y2 } = self.p2;
    36. 2.0 * ((x1 - x2).abs() + (y1 - y2).abs())
    37. }
    38. // 这个方法要求调用者对象是可变的
    39. // `&mut self` 为 `self: &mut Self` 的语法糖
    40. fn translate(&mut self, x: f64, y: f64) {
    41. self.p1.x += x;
    42. self.p2.x += x;
    43. self.p1.y += y;
    44. self.p2.y += y;
    45. }
    46. }
    47. // `Pair` 含有的资源:两个堆分配的整型
    48. struct Pair(Box<i32>, Box<i32>);
    49. impl Pair {
    50. // 这个方法“消费”调用者对象的资源
    51. // `self` 为 `self: Self` 的语法糖
    52. fn destroy(self) {
    53. // 解构 `self`
    54. let Pair(first, second) = self;
    55. println!("Destroying Pair({}, {})", first, second);
    56. // `first` 和 `second` 离开作用域后释放
    57. }
    58. }
    59. fn main() {
    60. let rectangle = Rectangle {
    61. // 静态方法使用双重冒号来调用
    62. p1: Point::origin(),
    63. p2: Point::new(3.0, 4.0),
    64. };
    65. // 实例方法通过点运算符来调用
    66. // 注意第一个参数 `&self` 是隐式传递的,比如:
    67. // `rectangle.perimeter()` === `Rectangle::perimeter(&rectangle)`
    68. println!("Rectangle perimeter: {}", rectangle.perimeter());
    69. println!("Rectangle area: {}", rectangle.area());
    70. let mut square = Rectangle {
    71. p1: Point::origin(),
    72. p2: Point::new(1.0, 1.0),
    73. };
    74. // 报错! `rectangle` 是不可变的,但这方法需要一个可变对象
    75. //rectangle.translate(1.0, 0.0);
    76. // 试一试 ^ 将此行注释去掉
    77. // 正常运行!可变对象可以调用可变方法
    78. square.translate(1.0, 1.0);
    79. let pair = Pair(Box::new(1), Box::new(2));
    80. pair.destroy();
    81. // 报错!前面的 `destroy` 调用“消费了” `pair`
    82. //pair.destroy();
    83. // 试一试 ^ 将此行注释去掉
    84. }