mirror of
https://github.com/RustyCab/LearnRustEasy.git
synced 2026-02-03 18:23:31 +08:00
update
This commit is contained in:
@@ -15,18 +15,30 @@
|
||||
- [Slice类型](./chapter_3/chapter_3_7_3.md)
|
||||
- [复合数据类型](./chapter_3/chapter_3_8.md)
|
||||
- [泛型](./chapter_3/chapter_3_9.md)
|
||||
- [3.13 闭包](./chapter_3/chapter_3_13.md)
|
||||
- [3.14 迭代器](./chapter_3/chapter_3_14.md)
|
||||
- [3.15 常见Collections](./chapter_3/chapter_3_15.md)
|
||||
- [3.15.1 Vector](./chapter_3/chapter_3_15_1.md)
|
||||
- [3.15.2 String](./chapter_3/chapter_3_15_2.md)
|
||||
- [3.15.3 HashMap](./chapter_3/chapter_3_15_3.md)
|
||||
- [3.15.4 HashSet](./chapter_3/chapter_3_15_4.md)
|
||||
- [3.15.5 LinkedList](./chapter_3/chapter_3_15_5.md)
|
||||
- [3.15.6 BTreeMap](./chapter_3/chapter_3_15_6.md)
|
||||
- [3.15.7 BTreeSet](./chapter_3/chapter_3_15_7.md)
|
||||
- [3.20 Rust并发编程](./chapter_3/chapter_3_20.md)
|
||||
- [3.21 unsafe编程](./chapter_3/chapter_3_21.md)
|
||||
- [Trait](./chapter_3/chapter_3_10.md)
|
||||
- [3.10.1 trait基础](./chapter_3/chapter_3_10_1.md)
|
||||
- [3.10.2 trait对象-todo](./chapter_3/chapter_3_10_2.md)
|
||||
- [3.10.3 常见的trait](./chapter_3/chapter_3_10_3.md)
|
||||
- [生命周期-todo](./chapter_3/chapter_3_11.md)
|
||||
- [错误处理-todo](./chapter_3/chapter_3_12.md)
|
||||
- [闭包](./chapter_3/chapter_3_13.md)
|
||||
- [迭代器](./chapter_3/chapter_3_14.md)
|
||||
- [常见Collections](./chapter_3/chapter_3_15.md)
|
||||
- [Vector](./chapter_3/chapter_3_15_1.md)
|
||||
- [String](./chapter_3/chapter_3_15_2.md)
|
||||
- [HashMap](./chapter_3/chapter_3_15_3.md)
|
||||
- [HashSet](./chapter_3/chapter_3_15_4.md)
|
||||
- [LinkedList](./chapter_3/chapter_3_15_5.md)
|
||||
- [BTreeMap](./chapter_3/chapter_3_15_6.md)
|
||||
- [BTreeSet](./chapter_3/chapter_3_15_7.md)
|
||||
- [智能指针-todo](./chapter_3/chapter_3_16.md)
|
||||
- [包、crate、模块-todo](./chapter_3/chapter_3_17.md)
|
||||
- [测试-todo](./chapter_3/chapter_3_18.md)
|
||||
- [再谈注释-todo](./chapter_3/chapter_3_19.md)
|
||||
- [Rust并发编程](./chapter_3/chapter_3_20.md)
|
||||
- [unsafe编程](./chapter_3/chapter_3_21.md)
|
||||
- [FFI介绍-todo](./chapter_3/chapter_3_22.md)
|
||||
- [宏介绍-todo](./chapter_3/chapter_3_23.md)
|
||||
- [Rust使用技巧]()
|
||||
- [Rust代码风格与格式化](./chapter_4/chapter_4_1.md)
|
||||
- [使用 Clippy 进行代码静态检查](./chapter_4/chapter_4_2.md)
|
||||
|
||||
5
src/chapter_3/chapter_3_10.md
Normal file
5
src/chapter_3/chapter_3_10.md
Normal file
@@ -0,0 +1,5 @@
|
||||
# 3.10 Trait
|
||||
|
||||
- [3.10.1 trait基础](./chapter_3_10_1.md)
|
||||
- [3.10.2 trait对象](./chapter_3_10_2.md)
|
||||
- [3.10.3 常见的trait](./chapter_3_10_3.md)
|
||||
509
src/chapter_3/chapter_3_10_1.md
Normal file
509
src/chapter_3/chapter_3_10_1.md
Normal file
@@ -0,0 +1,509 @@
|
||||
# 3.10.1 trait基础
|
||||
|
||||
trait定义了一组可以被共享的行为,只要实现了trait,就可以在代码中使用这组行为,它类似于其它语言中的接口(interface):
|
||||
- 可以通过trait以抽象的方式定义共享的行为;
|
||||
- 可以使用trait bounds指定泛型是任何拥有特定行为的类型。
|
||||
|
||||
## 1. 定义trait
|
||||
|
||||
定义trait就是定义一组行为,如下:
|
||||
|
||||
```rust
|
||||
pub trait GetInformation {
|
||||
fn get_name(&self) -> &String;
|
||||
fn get_age(&self) -> u32;
|
||||
}
|
||||
```
|
||||
|
||||
上述代码定义了一个叫做`GetInfomation`的trait,该trait提供了`get_name`和`get_age`方法。
|
||||
|
||||
## 2. 为类型实现trait
|
||||
|
||||
- 为类型实现trait
|
||||
|
||||
代码示例如下:
|
||||
```rust
|
||||
// 定义trait
|
||||
pub trait GetInformation {
|
||||
fn get_name(&self) -> &String;
|
||||
fn get_age(&self) -> u32;
|
||||
}
|
||||
|
||||
pub struct Student {
|
||||
pub name: String,
|
||||
pub age: u32,
|
||||
}
|
||||
// 为Student类型实现GetInformation trait
|
||||
impl GetInformation for Student {
|
||||
fn get_name(&self) -> &String {
|
||||
&self.name
|
||||
}
|
||||
fn get_age(&self) -> u32 {
|
||||
self.age
|
||||
}
|
||||
}
|
||||
|
||||
pub struct Teacher {
|
||||
pub name: String,
|
||||
pub age: u32,
|
||||
}
|
||||
// 为Teacher类型实现GetInformation trait
|
||||
impl GetInformation for Teacher {
|
||||
fn get_name(&self) -> &String {
|
||||
&self.name
|
||||
}
|
||||
fn get_age(&self) -> u32 {
|
||||
self.age
|
||||
}
|
||||
}
|
||||
|
||||
fn main() {
|
||||
let s = Student {
|
||||
name: "alice".to_string(),
|
||||
age: 18,
|
||||
};
|
||||
// 可以在类型Student上使用GetInfomation trait中定义的方法
|
||||
println!("s.name = {:?}, s.age = {:?}", s.get_name(), s.get_age());
|
||||
|
||||
let t = Teacher {
|
||||
name: "bob".to_string(),
|
||||
age: 25,
|
||||
};
|
||||
// 可以类型Teacher使用GetInfomation trait中定义的方法
|
||||
println!("t.name = {:?}, t.age = {:?}", t.get_name(), t.get_age());
|
||||
}
|
||||
```
|
||||
|
||||
- 可以在trait定义时提供默认实现
|
||||
|
||||
可以在定义trait的时候提供默认的行为,trait的类型可以使用默认的行为,示例如下:
|
||||
```rust
|
||||
// 定义trait
|
||||
pub trait GetInformation {
|
||||
fn get_name(&self) -> &String;
|
||||
fn get_age(&self) -> u32 { // 在定义trait时就提供默认实现
|
||||
25u32
|
||||
}
|
||||
}
|
||||
|
||||
pub struct Student {
|
||||
pub name: String,
|
||||
pub age: u32,
|
||||
}
|
||||
// 为Student类型实现GetInformation trait
|
||||
impl GetInformation for Student {
|
||||
fn get_name(&self) -> &String {
|
||||
&self.name
|
||||
}
|
||||
// 实现get_age方法,Student不会使用trait定义时的默认实现
|
||||
fn get_age(&self) -> u32 {
|
||||
self.age
|
||||
}
|
||||
}
|
||||
|
||||
pub struct Teacher {
|
||||
pub name: String,
|
||||
pub age: u32,
|
||||
}
|
||||
// 为Teacher类型实现GetInformation trait
|
||||
impl GetInformation for Teacher {
|
||||
fn get_name(&self) -> &String {
|
||||
&self.name
|
||||
}
|
||||
// 不实现get_age方法,将使用trait的默认实现
|
||||
}
|
||||
|
||||
fn main() {
|
||||
let s = Student {
|
||||
name: "alice".to_string(),
|
||||
age: 18,
|
||||
};
|
||||
// 可以在类型Student上使用GetInfomation trait中定义的方法
|
||||
// 输出t.name = "bob", t.age = 25
|
||||
println!("s.name = {:?}, s.age = {:?}", s.get_name(), s.get_age());
|
||||
|
||||
let t = Teacher {
|
||||
name: "bob".to_string(),
|
||||
age: 25,
|
||||
};
|
||||
// 可以类型Teacher使用GetInfomation trait中定义的方法(t.get_age将使用定义trait时的默认方法)
|
||||
// 输出t.name = "bob", t.age = 25
|
||||
println!("t.name = {:?}, t.age = {:?}", t.get_name(), t.get_age());
|
||||
}
|
||||
```
|
||||
|
||||
如果定义trait时提供了某个方法的默认实现,则:
|
||||
- 如果为类型实现该trait时,为该类型实现了此方法,则使用自己实现的方法(如上面示例中的Student类型);
|
||||
- 如果为类型实现该trait时,没有为该类型实现此方法,则该类型使用trait提供的默认实现(如上面的Teacher类型)。
|
||||
|
||||
## 3. trait作为参数
|
||||
|
||||
- trait作为参数
|
||||
trait可以用来参数,示例如下:
|
||||
|
||||
```rust
|
||||
// 定义trait
|
||||
pub trait GetInformation {
|
||||
fn get_name(&self) -> &String;
|
||||
fn get_age(&self) -> u32 {
|
||||
25u32
|
||||
}
|
||||
}
|
||||
|
||||
pub struct Student {
|
||||
pub name: String,
|
||||
pub age: u32,
|
||||
}
|
||||
// 为Student类型实现GetInformation trait
|
||||
impl GetInformation for Student {
|
||||
fn get_name(&self) -> &String {
|
||||
&self.name
|
||||
}
|
||||
fn get_age(&self) -> u32 {
|
||||
self.age
|
||||
}
|
||||
}
|
||||
|
||||
pub struct Teacher {
|
||||
pub name: String,
|
||||
pub age: u32,
|
||||
}
|
||||
// 为Teacher类型实现GetInformation trait
|
||||
impl GetInformation for Teacher {
|
||||
fn get_name(&self) -> &String {
|
||||
&self.name
|
||||
}
|
||||
}
|
||||
|
||||
// 参数类型必须是实现了GetInfomation trait的类型
|
||||
pub fn print_information(item: impl GetInformation) {
|
||||
println!("name = {}", item.get_name());
|
||||
println!("age = {}", item.get_age());
|
||||
}
|
||||
|
||||
fn main() {
|
||||
let s = Student {
|
||||
name: "alice".to_string(),
|
||||
age: 18,
|
||||
};
|
||||
print_information(s);
|
||||
|
||||
let t = Teacher {
|
||||
name: "bob".to_string(),
|
||||
age: 25,
|
||||
};
|
||||
print_information(t);
|
||||
}
|
||||
```
|
||||
|
||||
在上面的例子中,函数`pub fn print_information(item: impl GetInformation)`的要求参数item必须实现`GetInformation trait`,否则无法调用该参数。
|
||||
|
||||
- 使用`trait bound`语法
|
||||
|
||||
上面中的print_information函数还可以写成如下:
|
||||
```rust
|
||||
// 使用trait bound的写法一
|
||||
pub fn print_information<T: GetInformation>(item: T) {
|
||||
println!("name = {}", item.get_name());
|
||||
println!("age = {}", item.get_age());
|
||||
}
|
||||
```
|
||||
|
||||
这种写法叫做Trait bound语法,它是Rust中用于指定泛型类型参数所需的trait的一种方式,它还可以使用where关键字写成如下:
|
||||
```rust
|
||||
// 使用trait bound的写法二
|
||||
pub fn print_information<T>(item: T)
|
||||
where
|
||||
T: GetInformation,
|
||||
{
|
||||
println!("name = {}", item.get_name());
|
||||
println!("age = {}", item.get_age());
|
||||
}
|
||||
```
|
||||
|
||||
- 通过“`+`”指定多个trait bound
|
||||
|
||||
可以要求类型实现多个trait,示例如下:
|
||||
```rust
|
||||
pub trait GetName {
|
||||
fn get_name(&self) -> &String;
|
||||
}
|
||||
pub trait GetAge {
|
||||
fn get_age(&self) -> u32;
|
||||
}
|
||||
|
||||
//使用trait bound写法一,类型T必须实现GetName和GetAge trait
|
||||
pub fn print_information1<T: GetName + GetAge>(item: T) {
|
||||
println!("name = {}", item.get_name());
|
||||
println!("age = {}", item.get_age());
|
||||
}
|
||||
|
||||
//使用trait bound写法二,类型T必须实现GetName和GetAge trait
|
||||
pub fn print_information2<T>(item: T)
|
||||
where
|
||||
T: GetName + GetAge,
|
||||
{
|
||||
println!("name = {}", item.get_name());
|
||||
println!("age = {}", item.get_age());
|
||||
}
|
||||
|
||||
#[derive(Clone)]
|
||||
struct Student {
|
||||
name: String,
|
||||
age: u32,
|
||||
}
|
||||
|
||||
impl GetName for Student {
|
||||
fn get_name(&self) -> &String {
|
||||
&self.name
|
||||
}
|
||||
}
|
||||
|
||||
impl GetAge for Student {
|
||||
fn get_age(&self) -> u32 {
|
||||
self.age
|
||||
}
|
||||
}
|
||||
|
||||
fn main() {
|
||||
let s = Student {
|
||||
name: "alice".to_string(),
|
||||
age: 18u32,
|
||||
};
|
||||
print_information1(s.clone());
|
||||
print_information1(s);
|
||||
}
|
||||
```
|
||||
|
||||
在上面的代码中,`print_information1`和`print_information2`函数要求其参数类型T必须实现`GetName`和`GetAge`两个trait,通过`+`来进行多个约束的连接。
|
||||
|
||||
## 4. 返回trait的类型
|
||||
|
||||
trait类型可以作为函数的返回类型,示例如下:
|
||||
```rust
|
||||
pub trait GetName {
|
||||
fn get_name(&self) -> &String;
|
||||
}
|
||||
|
||||
struct Student {
|
||||
name: String,
|
||||
}
|
||||
|
||||
impl GetName for Student {
|
||||
fn get_name(&self) -> &String {
|
||||
&self.name
|
||||
}
|
||||
}
|
||||
|
||||
// trait类型作为返回的参数
|
||||
pub fn produce_item_with_name() -> impl GetName {
|
||||
// 返回一个实现了GetName trait的类型
|
||||
Student {
|
||||
name: "alice".to_string(),
|
||||
}
|
||||
}
|
||||
|
||||
fn main() {
|
||||
let s = produce_item_with_name();
|
||||
println!("name: {:?}", s.get_name());
|
||||
}
|
||||
```
|
||||
|
||||
上面代码中,`produce_item_with_name`函数返回了一个实现了`GetName trait`的类型。不过需要注意的是,这种方式返回的是单一类型,例如如下的代码就是错误的,无法编译通过:
|
||||
```rust
|
||||
pub trait GetName {
|
||||
fn get_name(&self) -> &String;
|
||||
}
|
||||
|
||||
struct Student {
|
||||
name: String,
|
||||
}
|
||||
|
||||
impl GetName for Student {
|
||||
fn get_name(&self) -> &String {
|
||||
&self.name
|
||||
}
|
||||
}
|
||||
struct Teacher {
|
||||
name: String,
|
||||
}
|
||||
|
||||
impl GetName for Teacher {
|
||||
fn get_name(&self) -> &String {
|
||||
&self.name
|
||||
}
|
||||
}
|
||||
|
||||
// 下面的代码将是错误的,无法编译通过,因为在编译时,返回的类型就确定为某一个实现了GetName trait的具体类型了
|
||||
pub fn produce_item_with_name(is_teacher: bool) -> impl GetName {
|
||||
let result = if is_teacher {
|
||||
Teacher {
|
||||
name: "alice".to_string(),
|
||||
}
|
||||
} else {
|
||||
Student {
|
||||
name: "alice".to_string(),
|
||||
}
|
||||
};
|
||||
|
||||
result
|
||||
}
|
||||
|
||||
fn main() {
|
||||
let s = produce_item_with_name(false);
|
||||
println!("name: {:?}", s.get_name());
|
||||
}
|
||||
```
|
||||
|
||||
错误原因分析(非常重要):
|
||||
上面的代码中的`produce_item_with_name`函数的定义实际上等价于如下:
|
||||
```rust
|
||||
pub fn produce_item_with_name<T: GetName>(is_teacher: bool) -> T {
|
||||
...
|
||||
|
||||
result
|
||||
}
|
||||
```
|
||||
|
||||
返回的值相当于是一个泛型,这个泛型要求要实现`GetName`这个trait。回顾泛型的知识,Rust实际上是在编译的时候把泛型换成了具体的类型,所以上面的定义中,T在编译时会变成确定的某个类型。所以在编译时,上面的代码可能被翻译成如下两种情况:
|
||||
|
||||
```rust
|
||||
// 编译时代码将被翻译成如下:
|
||||
pub fn produce_item_with_name(is_teacher: bool) -> Student {
|
||||
let result = if is_teacher {
|
||||
Teacher { name: "alice".to_string() }
|
||||
} else {
|
||||
Student { name: "alice".to_string() }
|
||||
};
|
||||
|
||||
result
|
||||
}
|
||||
|
||||
// 也可能翻译成如下:
|
||||
pub fn produce_item_with_name(is_teacher: bool) -> Student {
|
||||
let result = if is_teacher {
|
||||
Teacher { name: "alice".to_string() }
|
||||
} else {
|
||||
Student { name: "alice".to_string() }
|
||||
};
|
||||
|
||||
result
|
||||
}
|
||||
```
|
||||
|
||||
无论是哪种情况,都是错误的。
|
||||
|
||||
那如果需要返回多种实现了trait的类型,则需要使用后续讲解的内容trait对象(3.9.2节)来满足需求。
|
||||
|
||||
## 5. 使用`trait bound`有条件的实现方法
|
||||
|
||||
通过使用带有 `trait bound `的泛型参数的`impl` 块,可以有条件地只为那些实现了特定 trait 的类型实现方法,示例如下:
|
||||
|
||||
```rust
|
||||
|
||||
pub trait GetName {
|
||||
fn get_name(&self) -> &String;
|
||||
}
|
||||
pub trait GetAge {
|
||||
fn get_age(&self) -> u32;
|
||||
}
|
||||
struct PeopleMatchInformation<T, U> {
|
||||
master: T,
|
||||
employee: U,
|
||||
}
|
||||
// 11-15行也可以写成: impl<T: GetName + GetAge, U: GetName + GetAge> PeopleMatchInformation<T, U>
|
||||
impl<T, U> PeopleMatchInformation<T, U>
|
||||
where
|
||||
T: GetName + GetAge, // T和U都必须实现GetName和GetAge trait
|
||||
U: GetName + GetAge,
|
||||
{
|
||||
fn print_all_information(&self) {
|
||||
println!("teacher name = {}", self.master.get_name());
|
||||
println!("teacher age = {}", self.master.get_age());
|
||||
println!("student name = {}", self.employee.get_name());
|
||||
println!("student age = {}", self.employee.get_age());
|
||||
}
|
||||
}
|
||||
//使用
|
||||
pub struct Teacher {
|
||||
pub name: String,
|
||||
pub age: u32,
|
||||
}
|
||||
impl GetName for Teacher {
|
||||
fn get_name(&self) -> &String {
|
||||
&(self.name)
|
||||
}
|
||||
}
|
||||
impl GetAge for Teacher {
|
||||
fn get_age(&self) -> u32 {
|
||||
self.age
|
||||
}
|
||||
}
|
||||
pub struct Student {
|
||||
pub name: String,
|
||||
pub age: u32,
|
||||
}
|
||||
impl GetName for Student {
|
||||
fn get_name(&self) -> &String {
|
||||
&(self.name)
|
||||
}
|
||||
}
|
||||
impl GetAge for Student {
|
||||
fn get_age(&self) -> u32 {
|
||||
self.age
|
||||
}
|
||||
}
|
||||
fn main() {
|
||||
let t = Teacher {
|
||||
name: String::from("andy"),
|
||||
age: 32,
|
||||
};
|
||||
let s = Student {
|
||||
name: String::from("harden"),
|
||||
age: 47,
|
||||
};
|
||||
let m = PeopleMatchInformation {
|
||||
master: t,
|
||||
employee: s,
|
||||
};
|
||||
m.print_all_information();
|
||||
}
|
||||
```
|
||||
|
||||
上面的代码中,就是为`PeopleMatchInformation`有条件的实现`print_all_information`方法。
|
||||
|
||||
## 6. 对任何实现了特定trait的类型有条件的实现trait
|
||||
|
||||
在Rust中,另外一种比较常见的trait的用法就是对实现了特定trait的类型有条件的实现trait,示例如下:
|
||||
|
||||
```rust
|
||||
// trait定义
|
||||
pub trait GetName {
|
||||
fn get_name(&self) -> &String;
|
||||
}
|
||||
pub trait PrintName {
|
||||
fn print_name(&self);
|
||||
}
|
||||
// 为实现了GetName trait的类型实现PrintName trait
|
||||
impl<T: GetName> PrintName for T {
|
||||
fn print_name(&self) {
|
||||
println!("name = {}", self.get_name());
|
||||
}
|
||||
}
|
||||
// 将为Student实现对应的trait
|
||||
pub struct Student {
|
||||
pub name: String,
|
||||
}
|
||||
impl GetName for Student {
|
||||
fn get_name(&self) -> &String {
|
||||
&(self.name)
|
||||
}
|
||||
}
|
||||
fn main() {
|
||||
let s = Student {
|
||||
name: String::from("Andy"),
|
||||
};
|
||||
s.print_name(); //student实现了GetName trait,因此可是直接使用PrintName trait中的函数print_name
|
||||
}
|
||||
```
|
||||
上面的例子中,就是为实现了`GetName trait`的类型实现`PrintName trait`。
|
||||
3
src/chapter_3/chapter_3_10_2.md
Normal file
3
src/chapter_3/chapter_3_10_2.md
Normal file
@@ -0,0 +1,3 @@
|
||||
# 3.10.2 trait对象
|
||||
|
||||
todo
|
||||
113
src/chapter_3/chapter_3_10_3.md
Normal file
113
src/chapter_3/chapter_3_10_3.md
Normal file
@@ -0,0 +1,113 @@
|
||||
# 3.10.3 常见的trait
|
||||
|
||||
Rust 常见的 trait 包括:
|
||||
- `std::fmt::Display`: 格式化打印用户友好字符串。
|
||||
- `std::fmt::Debug`: 格式化打印调试字符串。
|
||||
- `std::cmp::PartialEq`: 比较值相等。
|
||||
- `std::cmp::PartialOrd`: 比较值顺序。
|
||||
- `std::cmp::Eq`: 类型完全相等关系。
|
||||
- `std::cmp::Ord`: 类型完全顺序关系。
|
||||
- `std::clone::Clone`: 创建类型副本。
|
||||
- `std::ops::Add`: 定义加法操作。
|
||||
- `std::ops::Mul`: 定义乘法操作。
|
||||
- `std::iter::Iterator`: 实现迭代器。
|
||||
|
||||
下面分别介绍:
|
||||
|
||||
## 1. std::fmt::Display:
|
||||
|
||||
```rust
|
||||
use std::fmt;
|
||||
|
||||
struct Person {
|
||||
name: String,
|
||||
age: u32,
|
||||
}
|
||||
|
||||
impl fmt::Display for Person {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
write!(f, "{} ({} years)", self.name, self.age)
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## 2. std::fmt::Debug:
|
||||
|
||||
```rust
|
||||
#[derive(Debug)]
|
||||
struct Person {
|
||||
name: String,
|
||||
age: u32,
|
||||
}
|
||||
```
|
||||
|
||||
## 3. std::cmp::PartialEq 和 std::cmp::Eq:
|
||||
```rust
|
||||
#[derive(PartialEq, Eq)]
|
||||
struct Point {
|
||||
x: i32,
|
||||
y: i32,
|
||||
}
|
||||
```
|
||||
|
||||
## 4. std::cmp::PartialOrd 和 std::cmp::Ord:
|
||||
|
||||
```rust
|
||||
#[derive(PartialOrd, Ord)]
|
||||
struct Point {
|
||||
x: i32,
|
||||
y: i32,
|
||||
}
|
||||
```
|
||||
|
||||
## 5. std::clone::Clone:
|
||||
|
||||
```rust
|
||||
#[derive(Clone)]
|
||||
struct Point {
|
||||
x: i32,
|
||||
y: i32,
|
||||
}
|
||||
```
|
||||
|
||||
## 6. std::ops::Add:
|
||||
|
||||
```rust
|
||||
use std::ops::Add;
|
||||
|
||||
struct Point {
|
||||
x: i32,
|
||||
y: i32,
|
||||
}
|
||||
|
||||
impl Add for Point {
|
||||
type Output = Point;
|
||||
|
||||
fn add(self, other: Point) -> Point {
|
||||
Point {
|
||||
x: self.x + other.x,
|
||||
y: self.y + other.y,
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## 7. std::iter::Iterator:
|
||||
```rust
|
||||
struct Counter {
|
||||
count: u32,
|
||||
}
|
||||
|
||||
impl Iterator for Counter {
|
||||
type Item = u32;
|
||||
|
||||
fn next(&mut self) -> Option<Self::Item> {
|
||||
self.count += 1;
|
||||
if self.count < 6 {
|
||||
Some(self.count)
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
3
src/chapter_3/chapter_3_11.md
Normal file
3
src/chapter_3/chapter_3_11.md
Normal file
@@ -0,0 +1,3 @@
|
||||
# 生命周期
|
||||
|
||||
todo
|
||||
3
src/chapter_3/chapter_3_12.md
Normal file
3
src/chapter_3/chapter_3_12.md
Normal file
@@ -0,0 +1,3 @@
|
||||
# 错误处理
|
||||
|
||||
todo
|
||||
3
src/chapter_3/chapter_3_16.md
Normal file
3
src/chapter_3/chapter_3_16.md
Normal file
@@ -0,0 +1,3 @@
|
||||
# 智能指针
|
||||
|
||||
todo
|
||||
3
src/chapter_3/chapter_3_17.md
Normal file
3
src/chapter_3/chapter_3_17.md
Normal file
@@ -0,0 +1,3 @@
|
||||
# 包、crate、模块
|
||||
|
||||
todo
|
||||
3
src/chapter_3/chapter_3_18.md
Normal file
3
src/chapter_3/chapter_3_18.md
Normal file
@@ -0,0 +1,3 @@
|
||||
# 测试
|
||||
|
||||
todo
|
||||
3
src/chapter_3/chapter_3_19.md
Normal file
3
src/chapter_3/chapter_3_19.md
Normal file
@@ -0,0 +1,3 @@
|
||||
# 再谈注释
|
||||
|
||||
todo
|
||||
3
src/chapter_3/chapter_3_22.md
Normal file
3
src/chapter_3/chapter_3_22.md
Normal file
@@ -0,0 +1,3 @@
|
||||
# FFI介绍
|
||||
|
||||
todo
|
||||
3
src/chapter_3/chapter_3_23.md
Normal file
3
src/chapter_3/chapter_3_23.md
Normal file
@@ -0,0 +1,3 @@
|
||||
# 宏介绍
|
||||
|
||||
todo
|
||||
@@ -1,6 +1,5 @@
|
||||
# 3.9 泛型
|
||||
|
||||
|
||||
泛型是具体类型或者其它属性的抽象代替,用于减少代码的重复。在编写Rust代码时,可以用泛型来表示各种各样的数据类型,等到编译阶段,泛型则被替换成它所代表的的具体的数据类型。
|
||||
|
||||
## 3.9.1 函数定义中的泛型
|
||||
|
||||
Reference in New Issue
Block a user