mirror of
https://github.com/ZiuChen/ZiuChen.github.io.git
synced 2025-08-18 23:49:33 +08:00
docs: rust note
This commit is contained in:
parent
25f4e199cd
commit
0649092513
@ -1512,6 +1512,138 @@ $ cargo run
|
|||||||
|
|
||||||
与函数不同的是,方法是在结构体的上下文被定义的(或者是枚举或 trait 对象的上下文)
|
与函数不同的是,方法是在结构体的上下文被定义的(或者是枚举或 trait 对象的上下文)
|
||||||
|
|
||||||
|
我们将前文中的 `area` 函数改写为定义于 `Rectangle` 结构体上的一个 `area` 方法:
|
||||||
|
|
||||||
|
```rs
|
||||||
|
#[derive(Debug)]
|
||||||
|
struct Rectangle {
|
||||||
|
width: u32,
|
||||||
|
height: u32,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Rectangle {
|
||||||
|
fn area(&self) -> u32 {
|
||||||
|
self.width * self.height
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
let rect1 = Rectangle {
|
||||||
|
width: 30,
|
||||||
|
height: 50,
|
||||||
|
};
|
||||||
|
|
||||||
|
println!(
|
||||||
|
"The area of the rectangle is {} square pixels.",
|
||||||
|
rect1.area()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
为了使函数定义于 `Rectangle` 的上下文中,我们使用 `impl` 关键字,在 `impl` 中的所有内容都将和 `Rectangle` 类型相关联。
|
||||||
|
|
||||||
|
将 `area` 函数的参数 `rectangle: &Rectangle` 改为 `&self`,这本质上是 `self: &Self` 的缩写。在一个 `impl` 块中,`Self` 类型是 `impl` 块的类型的别名。
|
||||||
|
|
||||||
|
- 方法的第一个参数必须有一个名为 `self` 的 `Self` 类型的参数;
|
||||||
|
- 要修改调用方法的实例,可以写为:`&mut self` 以获得所有权;
|
||||||
|
|
||||||
|
特别地,我们可以选择将方法的名称与结构中的一个字段相同,例如我们可以定义一个名为 `width` 的方法:
|
||||||
|
|
||||||
|
```rs
|
||||||
|
impl Rectangle {
|
||||||
|
fn width(&self) -> bool {
|
||||||
|
// 当 self.width > 0 时返回 true
|
||||||
|
self.width > 0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
let rect1 = Rectangle {
|
||||||
|
width: 30,
|
||||||
|
height: 50,
|
||||||
|
};
|
||||||
|
|
||||||
|
if rect1.width() {
|
||||||
|
println!("The rectangle has a nonzero width; it is {}", rect1.width);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
在使用 `width` 方法时,需要用 `()` 来调用它。
|
||||||
|
|
||||||
|
你也可以将 `width` 方法仅仅返回 `self.width` 的值,这样就可以通过这个 getter 访问到 `self.width` 的值。
|
||||||
|
|
||||||
|
下面我们编写一个带参数的方法 `can_hold` 用于检查一个 `Rectangle` 是否可以包含另一个 `Rectangle`:
|
||||||
|
|
||||||
|
```rs
|
||||||
|
struct Rectangle {
|
||||||
|
width: u32,
|
||||||
|
height: u32,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Rectangle {
|
||||||
|
fn area(&self) -> u32 {
|
||||||
|
self.width * self.height
|
||||||
|
}
|
||||||
|
|
||||||
|
fn width(&self) -> bool {
|
||||||
|
self.width > 0
|
||||||
|
}
|
||||||
|
|
||||||
|
fn can_hold(&self, other: &Rectangle) -> bool {
|
||||||
|
self.width > other.width && self.height > other.height
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
let rec1 = Rectangle {
|
||||||
|
width: 30,
|
||||||
|
height: 50,
|
||||||
|
};
|
||||||
|
let rec2 = Rectangle {
|
||||||
|
width: 10,
|
||||||
|
height: 40,
|
||||||
|
};
|
||||||
|
|
||||||
|
println!(
|
||||||
|
"The area of the rectangle is {} square pixels.",
|
||||||
|
rec1.area()
|
||||||
|
);
|
||||||
|
println!("rec1 can hold rec2: {}", rec1.can_hold(&rec2));
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
我们给 `can_hold` 传入了第二个参数 `other`,它是一个 `Rectangle` 实例的不可变借用。
|
||||||
|
|
||||||
|
在调用 `can_hold` 时,直接将 `Rectangle` 实例传入即可,这时所有权仍然被 `rec2` 保持,因此我们可以在调用完 `can_hold` 后继续使用 `rec2`。
|
||||||
|
|
||||||
|
所有在 `impl` 块中定义的函数被称为 **关联函数**,因为它们与 `impl` 后面命名的类型相关。我们可以定义不以 `self` 为第一参数的关联函数(因此不是方法)。
|
||||||
|
|
||||||
|
关联函数并不作用于一个实例,一个最好的关联函数例子就是 `String::from` 函数。
|
||||||
|
|
||||||
|
不是方法的关联函数经常被用作返回一个结构体新实例的构造函数(名称通常为 `new`,但实际上 `new` 并不是一个关键字)。
|
||||||
|
|
||||||
|
例如我们可以编写一个名为 `square` 的关联函数,它接收一个参数同时作为宽和高,通过 `square` 声明 `Rectangle` 时不必指定两次同样的值:
|
||||||
|
|
||||||
|
```rs
|
||||||
|
impl Rectangle {
|
||||||
|
fn square(size: u32) -> Self {
|
||||||
|
Rectangle {
|
||||||
|
width: size,
|
||||||
|
height: size,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
let sq = Rectangle::square(30); // 创建一个 30*30 的正方形
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
使用结构体名和 `::` 语法来调用这个关联函数。这个函数位于结构体的命名空间中,`::` 语法用于关联函数和模块创建的命名空间。
|
||||||
|
|
||||||
|
每个结构体都允许拥有多个 `impl` 块,你可以在不同的 `impl` 中声明方法或关联函数,在后面的章节中会见到实用的多 `impl` 块的用例。
|
||||||
|
|
||||||
## 枚举和模式匹配
|
## 枚举和模式匹配
|
||||||
|
|
||||||
### 枚举的定义
|
### 枚举的定义
|
||||||
|
Loading…
x
Reference in New Issue
Block a user