通过例子学习Rust

25 方法

Methods are functions attached to objects, these methods have access to the data of the object and its other methods via the self keyword. Methods are defined under a impl block.

use std::num::Float; // To be able to use .abs(), you must include this struct Point { x: f64, y: f64, } // Implementation block, all `Point` methods go in here impl Point { // This is a static method // Static methods don't need to be called by an instance // These methods are generally used as constructors fn origin() -> Point { Point { x: 0.0, y: 0.0 } } // Another static method, that takes two arguments fn new(x: f64, y: f64) -> Point { Point { x: x, y: y } } } struct Rectangle { p1: Point, p2: Point, } impl Rectangle { // This is an instance method // `&self` is sugar for `self: &Self`, where `Self` is the type of the // caller object. In this case `Self` = `Rectangle` fn area(&self) -> f64 { // `self` gives access to the struct fields via the dot operator let Point { x: x1, y: y1 } = self.p1; let Point { x: x2, y: y2 } = self.p2; // `abs` is a `f64` method that returns the absolute value of the // caller ((x1 - x2) * (y1 - y2)).abs() } fn perimeter(&self) -> f64 { let Point { x: x1, y: y1 } = self.p1; let Point { x: x2, y: y2 } = self.p2; 2.0 * (x1 - x2).abs() + 2.0 * (y1 - y2).abs() } // This method requires the caller object to be mutable // `&mut self` desugars to `self: &mut Self` fn translate(&mut self, x: f64, y: f64) { self.p1.x += x; self.p2.x += x; self.p1.y += y; self.p2.y += y; } } // `Pair` owns resources: two heap allocated integers struct Pair(Box<int>, Box<int>); impl Pair { // This method "consumes" the resources of the caller object // `self` desugars to `self: Self` fn destroy(self) { // Destructure `self` let Pair(first, second) = self; println!("Destroying Pair({}, {})", first, second); // `first` and `second` go out of scope and get freed } } fn main() { let rectangle = Rectangle { // Static methods are called using double colons p1: Point::origin(), p2: Point::new(3.0, 4.0), }; // Instance method are called using the dot operator // Note that the first argument `&self` is implicitly passed, i.e. // `rectangle.perimeter()` === `perimeter(&rectangle)` println!("Rectangle perimeter: {}", rectangle.perimeter()); println!("Rectangle area: {}", rectangle.area()); let mut square = Rectangle { p1: Point::origin(), p2: Point::new(1.0, 1.0), }; // Error! `rectangle` is immutable, but this method requires a mutable // object //rectangle.translate(1.0, 0.0); // TODO ^ Try uncommenting this line // Ok, mutable object can call mutable methods square.translate(1.0, 1.0); let pair = Pair(box 1, box 2); pair.destroy(); // Error! Previous `destroy` call "consumed" `pair` //pair.destroy(); // TODO ^ Try uncommenting this line }