Update trait/generic.md

pull/210/head
Allan Downey 3 years ago
parent f161c021f6
commit 2c574496e5

@ -100,7 +100,7 @@ help: consider restricting type parameter `T` // 考虑对T进行类型上的限
还记得我们一开始的 `add` 泛型函数吗?如果你运行它,会得到以下的报错: 还记得我们一开始的 `add` 泛型函数吗?如果你运行它,会得到以下的报错:
```console ```console
error[E0369]: cannot add `T` to `T` // 无法将`T`类型跟`T`类型进行相加 error[E0369]: cannot add `T` to `T` // 无法将 `T` 类型跟 `T` 类型进行相加
--> src/main.rs:2:7 --> src/main.rs:2:7
| |
2 | a + b 2 | a + b
@ -114,7 +114,7 @@ help: consider restricting type parameter `T`
| +++++++++++++++++++++++++++ | +++++++++++++++++++++++++++
``` ```
同样的,不是所有`T`类型都能进行相加操作,因此我们需要用`std::ops::Add<Output = T>`T进行限制 同样的,不是所有 `T` 类型都能进行相加操作,因此我们需要用 `std::ops::Add<Output = T>``T` 进行限制:
```rust ```rust
fn add<T: std::ops::Add<Output = T>>(a:T, b:T) -> T { fn add<T: std::ops::Add<Output = T>>(a:T, b:T) -> T {
a + b a + b
@ -123,7 +123,7 @@ fn add<T: std::ops::Add<Output = T>>(a:T, b:T) -> T {
进行如上修改后,就可以正常运行。 进行如上修改后,就可以正常运行。
## 结构体中使用泛型 ## 结构体中使用泛型
结构体中的字段类型也可以用泛型来定义,下面代码定义了一个坐标点`Point`,它可以存放任何类型的坐标值: 结构体中的字段类型也可以用泛型来定义,下面代码定义了一个坐标点 `Point`,它可以存放任何类型的坐标值:
```rust ```rust
struct Point<T> { struct Point<T> {
x: T, x: T,
@ -137,7 +137,7 @@ fn main() {
``` ```
这里有两点需要特别的注意: 这里有两点需要特别的注意:
- **提前声明**,跟泛型函数定义类似,首先我们在使用泛型参数之前必需要进行声明`Point<T>`,接着就可以在结构体的字段类型中使用`T`来替代具体的类型 - **提前声明**,跟泛型函数定义类似,首先我们在使用泛型参数之前必需要进行声明 `Point<T>`,接着就可以在结构体的字段类型中使用 `T` 来替代具体的类型
- **x和y是相同的类型** - **x和y是相同的类型**
第二点非常重要,如果使用不同的类型,那么它会导致下面代码的报错: 第二点非常重要,如果使用不同的类型,那么它会导致下面代码的报错:
@ -187,7 +187,7 @@ enum Option<T> {
} }
``` ```
`Option<T>` 是一个拥有泛型 `T`,它第一个成员是 `Some(T)`,存放了一个类型为`T`的值。得益于泛型的引入,我们可以在任何一个需要返回值的函数中,去使用 `Option<T>` 枚举类型来做为返回值,用于返回一个任意类型的值 `Some(T)`,或者没有值 `None` `Option<T>` 是一个拥有泛型 `T` 的枚举类型,它第一个成员是 `Some(T)`,存放了一个类型为 `T` 的值。得益于泛型的引入,我们可以在任何一个需要返回值的函数中,去使用 `Option<T>` 枚举类型来做为返回值,用于返回一个任意类型的值 `Some(T)`,或者没有值 `None`
对于枚举而言,卧龙凤雏永远是绕不过去的存在:如果是 `Option` 是卧龙,那么 `Result` 就一定是凤雏,得两者可得天下: 对于枚举而言,卧龙凤雏永远是绕不过去的存在:如果是 `Option` 是卧龙,那么 `Result` 就一定是凤雏,得两者可得天下:
```rust ```rust
@ -199,7 +199,7 @@ enum Result<T, E> {
这个枚举和 `Option` 一样,主要用于函数返回值,与 `Option` 用于值的存在与否不同,`Result `关注的主要是值的正确性。 这个枚举和 `Option` 一样,主要用于函数返回值,与 `Option` 用于值的存在与否不同,`Result `关注的主要是值的正确性。
如果函数正常运行,则最后返回一个 `Ok(T)``T` 是函数具体的返回值类型,如果函数异常运行,则返回一个 `Err(E)``E` 是错误类型。例如打开一个文件:如果成功打开文件,则返回`Ok(std::fs::File)`,因此 `T` 对应的是 `std::fs::File` 类型;而当打开文件时出现问题时,返回 `Err(std::io::Error)``E` 对应的就是`std::io::Error` 类型。 如果函数正常运行,则最后返回一个 `Ok(T)``T` 是函数具体的返回值类型,如果函数异常运行,则返回一个 `Err(E)``E` 是错误类型。例如打开一个文件:如果成功打开文件,则返回 `Ok(std::fs::File)`,因此 `T` 对应的是 `std::fs::File` 类型;而当打开文件时出现问题时,返回 `Err(std::io::Error)``E` 对应的就是 `std::io::Error` 类型。
## 方法中使用泛型 ## 方法中使用泛型
上一章中,我们讲到什么是方法以及如何在结构体和枚举上定义方法。方法上也可以使用泛型: 上一章中,我们讲到什么是方法以及如何在结构体和枚举上定义方法。方法上也可以使用泛型:
@ -264,7 +264,7 @@ impl Point<f32> {
``` ```
这段代码意味着 `Point<f32>` 类型会有一个方法 `distance_from_origin`,而其他 `T` 不是 `f32` 类型的 `Point<T> `实例则没有定义此方法。这个方法计算点实例与坐标`(0.0, 0.0)` 之间的距离,并使用了只能用于浮点型的数学运算符。 这段代码意味着 `Point<f32>` 类型会有一个方法 `distance_from_origin`,而其他 `T` 不是 `f32` 类型的 `Point<T> `实例则没有定义此方法。这个方法计算点实例与坐标`(0.0, 0.0)` 之间的距离,并使用了只能用于浮点型的数学运算符。
这样我们就能针对特定的泛型类型实现某个特定的方法,对于其它泛型类型,该方法则并无定义 这样我们就能针对特定的泛型类型实现某个特定的方法,对于其它泛型类型则没有定义该方法
@ -369,7 +369,7 @@ where
fn main() { fn main() {
something([0u8; 0]); // ok something([0u8; 0]); // ok
something([0u8; 512]); // ok something([0u8; 512]); // ok
something([0u8; 1024]); // 编译错误数组长度是1024自己超过了768字节的参数长度限制 something([0u8; 1024]); // 编译错误数组长度是1024字节超过了768字节的参数长度限制
} }
// --- // ---

Loading…
Cancel
Save