Rust函数方法(method)

​ 方法是依附于对象的函数,在go语言中称之为结构体方法。在rust中方法通过关键字self作为参数来访问对象中的数据。方法在impl代码块中定义。

​ 例一:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
//结构体Point float64类型的x和y
struct Point {
x: f64,
y: f64,
}

// 结构体方法
// 实现的代码块,`Point` 的所有方法都在这里给出
impl Point {
// 这是一个静态方法(static method)
// 静态方法不需要被实例调用
// 这类方法一般用作构造器(constructor)
//Point结构体的方法origin,返回值为结构体Point
fn origin() -> Point {
Point { x: 0.0, y: 0.0 }
}

// 另外一个静态方法,需要两个参数:
//Point结构体的方法new,参数为float64类型的x和y,返回值为结构体Point
fn new(x: f64, y: f64) -> Point {
Point { x: x, y: y }
}
}

​ 以上struct Point定义对象impl Point用于实现对象Point的方法,分别为origin和new,这两个方法数据静态方法。一般用于对象的构造。构造方法Point::origin()或者Point::new(1.0,2.0)

​ 例二:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
//结构体Rectangle,结构体嵌套
struct Rectangle {
p1: Point,
p2: Point,
}

impl Rectangle {
// 这是一个实例方法(instance method)
// `&self` 是 `self: &Self` 的语法糖(sugar),其中 `Self` 是方法调用者的
// 类型。在这个例子中 `Self` = `Rectangle`

//self为结构体Rectangle,&取地址,返回float64类型的值
fn area(&self) -> f64 {
// `self` 通过点运算符来访问结构体字段
let Point { x: x1, y: y1 } = self.p1;
let Point { x: x2, y: y2 } = self.p2;

// `abs` 是一个 `f64` 类型的方法,返回调用者的绝对值
((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() + (y1 - y2).abs())
}

// 这个方法要求调用者是可变的
// `&mut self` 为 `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;
}
}

​ 这里Rectangle也是一个结构体,其结构体成员类型也为结构体Point类型,为结构体嵌套。其结构体方法中关键字self作为参数来访问对象中的数据。类似于golang中func(r *Rectangle)funName(){}。调用方式:

1
2
3
4
5
6
7
8
let rectangle = Rectangle {
// 静态方法使用双冒号调用
p1: Point::origin(),
p2: Point::new(3.0, 4.0),
};
println!("Rectangle perimeter: {}", rectangle.perimeter());
println!("Rectangle area: {}", rectangle.area());
//如果要调用translate,必须定义可变mut

​ 例三:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
// `Pair` 拥有资源:两个堆分配的整型
struct Pair(Box<i32>, Box<i32>);

impl Pair {
// 这个方法会 “消耗” 调用者的资源
// `self` 为 `self: Self` 的语法糖
fn destroy(self) {
// 解构 `self`
let Pair(first, second) = self;

println!("Destroying Pair({}, {})", first, second);

// `first` 和 `second` 离开作用域后释放
}
}

​ 这里其实主要要注意的是参数离开作用域后释放:

1
2
3
4
5
   let pair = Pair(Box::new(1), Box::new(2));
//不报错,调用后释放
pair.destroy();
//报错,已经被释放
pair.destroy();