Merge branch 'sunface:main' into main

pull/1126/head
Rustln 2 years ago committed by GitHub
commit 26f6d3b9af
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -645,6 +645,10 @@ where
依然是熟悉的配方 `longest`,但是多了一段废话: `ann`,因为要用格式化 `{}` 来输出 `ann`,因此需要它实现 `Display` 特征。 依然是熟悉的配方 `longest`,但是多了一段废话: `ann`,因为要用格式化 `{}` 来输出 `ann`,因此需要它实现 `Display` 特征。
## 课后练习
> [Rust By Practice](https://zh.practice.rs/lifetime/basic.html),支持代码在线编辑和运行,并提供详细的习题解答。(本节暂无习题解答)
## 总结 ## 总结
我不知道支撑我一口气写完的勇气是什么,也许是不做完不爽夫斯基,也许是一些读者对本书的期待,不管如何,这章足足写了 17000 字,可惜不是写小说,不然肯定可以获取很多月票 :) 我不知道支撑我一口气写完的勇气是什么,也许是不做完不爽夫斯基,也许是一些读者对本书的期待,不管如何,这章足足写了 17000 字,可惜不是写小说,不然肯定可以获取很多月票 :)

@ -184,6 +184,10 @@ fn main() {
以上代码不出所料会报错,原因在于虽然字符串字面量 "I'm in read-only memory" 的生命周期是 `'static`,但是持有它的引用并不是,它的作用域在内部花括号 `}` 处就结束了。 以上代码不出所料会报错,原因在于虽然字符串字面量 "I'm in read-only memory" 的生命周期是 `'static`,但是持有它的引用并不是,它的作用域在内部花括号 `}` 处就结束了。
## 课后练习
> [Rust By Practice](https://zh.practice.rs/lifetime/static.html),支持代码在线编辑和运行,并提供详细的习题解答。(本节暂无习题解答)
## 总结 ## 总结

@ -72,5 +72,5 @@ fn main() {
## 课后练习 ## 课后练习
> [Rust By Practice](https://zh.practice.rs/basic-types/char-bool-unit.html),支持代码在线编辑和运行,并提供详细的[习题解答](https://github.com/sunface/rust-by-practice)。 > [Rust By Practice](https://zh.practice.rs/basic-types/char-bool-unit.html),支持代码在线编辑和运行,并提供详细的[习题解答](https://github.com/sunface/rust-by-practice/blob/master/solutions/basic-types/char-bool.md)。

@ -192,4 +192,4 @@ fn forever() -> ! {
## 课后练习 ## 课后练习
> [Rust By Practice](https://zh.practice.rs/basic-types/functions.html),支持代码在线编辑和运行,并提供详细的[习题解答](https://github.com/sunface/rust-by-practice)。 > [Rust By Practice](https://zh.practice.rs/basic-types/functions.html),支持代码在线编辑和运行,并提供详细的[习题解答](https://github.com/sunface/rust-by-practice/blob/master/solutions/basic-types/functions.md)。

@ -338,7 +338,7 @@ use num::complex::Complex;
## 课后练习 ## 课后练习
> [Rust By Practice](https://zh.practice.rs/basic-types/numbers.html),支持代码在线编辑和运行,并提供详细的[习题解答](https://github.com/sunface/rust-by-practice)。 > [Rust By Practice](https://zh.practice.rs/basic-types/numbers.html),支持代码在线编辑和运行,并提供详细的[习题解答](https://github.com/sunface/rust-by-practice/blob/master/solutions/basic-types/numbers.md)。

@ -105,5 +105,5 @@ fn ret_unit_type() {
## 课后练习 ## 课后练习
> [Rust By Practice](https://zh.practice.rs/basic-types/statements-expressions.html),支持代码在线编辑和运行,并提供详细的[习题解答](https://github.com/sunface/rust-by-practice)。 > [Rust By Practice](https://zh.practice.rs/basic-types/statements-expressions.html),支持代码在线编辑和运行,并提供详细的[习题解答](https://github.com/sunface/rust-by-practice/blob/master/solutions/basic-types/statements.md)。

@ -304,4 +304,4 @@ assert_eq!(hash.get(&42), Some(&"the answer"));
## 课后练习 ## 课后练习
> [Rust By Practice](https://zh.practice.rs/collections/hashmap.html),支持代码在线编辑和运行,并提供详细的[习题解答](https://github.com/sunface/rust-by-practice)。 > [Rust By Practice](https://zh.practice.rs/collections/hashmap.html),支持代码在线编辑和运行,并提供详细的[习题解答](https://github.com/sunface/rust-by-practice/blob/master/solutions/collections/Hashmap.md)。

@ -236,4 +236,4 @@ fn main() {
## 课后练习 ## 课后练习
> [Rust By Practice](https://zh.practice.rs/collections/vector.html),支持代码在线编辑和运行,并提供详细的[习题解答](https://github.com/sunface/rust-by-practice)。 > [Rust By Practice](https://zh.practice.rs/collections/vector.html),支持代码在线编辑和运行,并提供详细的[习题解答](https://github.com/sunface/rust-by-practice/blob/master/solutions/collections/Vector.md)。

@ -469,3 +469,7 @@ Green
在 Rust 中,注释分为三个主要类型:代码注释、文档注释、包和模块注释,每个注释类型都拥有两种形式:行注释和块注释,熟练掌握包模块和注释的知识,非常有助于我们创建工程性更强的项目。 在 Rust 中,注释分为三个主要类型:代码注释、文档注释、包和模块注释,每个注释类型都拥有两种形式:行注释和块注释,熟练掌握包模块和注释的知识,非常有助于我们创建工程性更强的项目。
如果读者看到这里对于包模块还是有些模糊,强烈建议回头看看相关的章节以及本章节的最后一个综合例子。 如果读者看到这里对于包模块还是有些模糊,强烈建议回头看看相关的章节以及本章节的最后一个综合例子。
## 课后练习
> [Rust By Practice](https://zh.practice.rs/comments-docs.html),支持代码在线编辑和运行,并提供详细的习题解答。(本节暂无习题解答)

@ -174,4 +174,4 @@ fn main() {
## 课后练习 ## 课后练习
> [Rust By Practice](https://zh.practice.rs/compound-types/array.html),支持代码在线编辑和运行,并提供详细的[习题解答](https://github.com/sunface/rust-by-practice)。 > [Rust By Practice](https://zh.practice.rs/compound-types/array.html),支持代码在线编辑和运行,并提供详细的[习题解答](https://github.com/sunface/rust-by-practice/blob/master/solutions/compound-types/array.md)。

@ -291,4 +291,4 @@ let none = plus_one(None);
## 课后练习 ## 课后练习
> [Rust By Practice](https://zh.practice.rs/compound-types/enum.html),支持代码在线编辑和运行,并提供详细的[习题解答](https://github.com/sunface/rust-by-practice)。 > [Rust By Practice](https://zh.practice.rs/compound-types/enum.html),支持代码在线编辑和运行,并提供详细的[习题解答](https://github.com/sunface/rust-by-practice/blob/master/solutions/compound-types/enum.md)。

@ -710,10 +710,13 @@ for b in "中国人".bytes() {
这个模式对编写 Rust 代码的方式有着深远的影响,在后面章节我们会进行更深入的介绍。 这个模式对编写 Rust 代码的方式有着深远的影响,在后面章节我们会进行更深入的介绍。
## 课后练习 ## 课后练习
> Rust By Practice支持代码在线编辑和运行并提供详细的习题解答。
- [字符串](https://zh.practice.rs/compound-types/string.html) > - [字符串](https://zh.practice.rs/compound-types/string.html)
- [切片](https://zh.practice.rs/compound-types/slice.html) > - [习题解答](https://github.com/sunface/rust-by-practice/blob/master/solutions/compound-types/string.md)
- [String](https://zh.practice.rs/collections/String.html) > - [切片](https://zh.practice.rs/compound-types/slice.html)
> - [习题解答](https://github.com/sunface/rust-by-practice/blob/master/solutions/compound-types/slice.md)
> - [String](https://zh.practice.rs/collections/String.html)
> - [习题解答](https://github.com/sunface/rust-by-practice/blob/master/solutions/collections/String.md)
<hr /> <hr />

@ -118,7 +118,7 @@ fn build_user(email: String, username: String) -> User {
因为 `user2` 仅仅在 `email` 上与 `user1` 不同,因此我们只需要对 `email` 进行赋值,剩下的通过结构体更新语法 `..user1` 即可完成。 因为 `user2` 仅仅在 `email` 上与 `user1` 不同,因此我们只需要对 `email` 进行赋值,剩下的通过结构体更新语法 `..user1` 即可完成。
`..` 语法表明凡是我们没有显声明的字段,全部从 `user1` 中自动获取。需要注意的是 `..user1` 必须在结构体的尾部使用。 `..` 语法表明凡是我们没有显声明的字段,全部从 `user1` 中自动获取。需要注意的是 `..user1` 必须在结构体的尾部使用。
> 结构体更新语法跟赋值语句 `=` 非常相像,因此在上面代码中,`user1` 的部分字段所有权被转移到 `user2` 中:`username` 字段发生了所有权转移,作为结果,`user1` 无法再被使用。 > 结构体更新语法跟赋值语句 `=` 非常相像,因此在上面代码中,`user1` 的部分字段所有权被转移到 `user2` 中:`username` 字段发生了所有权转移,作为结果,`user1` 无法再被使用。
> >
@ -426,5 +426,5 @@ $ cargo run
## 课后练习 ## 课后练习
> [Rust By Practice](https://zh.practice.rs/compound-types/struct.html),支持代码在线编辑和运行,并提供详细的[习题解答](https://github.com/sunface/rust-by-practice)。 > [Rust By Practice](https://zh.practice.rs/compound-types/struct.html),支持代码在线编辑和运行,并提供详细的[习题解答](https://github.com/sunface/rust-by-practice/blob/master/solutions/compound-types/struct.md)。

@ -76,4 +76,4 @@ fn calculate_length(s: String) -> (String, usize) {
## 课后练习 ## 课后练习
> [Rust By Practice](https://zh.practice.rs/compound-types/tuple.html),支持代码在线编辑和运行,并提供详细的[习题解答](https://github.com/sunface/rust-by-practice)。 > [Rust By Practice](https://zh.practice.rs/compound-types/tuple.html),支持代码在线编辑和运行,并提供详细的[习题解答](https://github.com/sunface/rust-by-practice/blob/master/solutions/compound-types/tuple.md)。

@ -318,3 +318,9 @@ unsafe fn shorten_invariant_lifetime<'b, 'c>(r: &'b mut R<'static>) -> &'b mut R
``` ```
以上例子非常先进!但是是非常不安全的 Rust 行为! 以上例子非常先进!但是是非常不安全的 Rust 行为!
## 课后练习
> Rust By Practice支持代码在线编辑和运行并提供详细的习题解答。本节暂无习题解答
> - [as](https://zh.practice.rs/type-conversions/as.html)
> - [From/Into](https://zh.practice.rs/type-conversions/from-into.html)
> - [其它转换](https://zh.practice.rs/type-conversions/others.html)

@ -108,3 +108,7 @@ error: a bin target must be available for `cargo run`
这种目录结构基本上是 Rust 的标准目录结构,在 `GitHub` 的大多数项目上,你都将看到它的身影。 这种目录结构基本上是 Rust 的标准目录结构,在 `GitHub` 的大多数项目上,你都将看到它的身影。
理解了包的概念,我们再来看看构成包的基本单元:模块。 理解了包的概念,我们再来看看构成包的基本单元:模块。
## 课后练习
> [Rust By Practice](https://zh.practice.rs/crate-module/crate.html),支持代码在线编辑和运行,并提供详细的[习题解答](https://github.com/sunface/rust-by-practice/blob/master/solutions/crate-module/crate.md)。

@ -325,3 +325,7 @@ so easy其实跟之前在同一个文件中也没有太大的不同但是
需要注意的是,和之前代码中 `mod front_of_house{..}` 的完整模块不同,现在的代码中,模块的声明和实现是分离的,实现是在单独的 `front_of_house.rs` 文件中,然后通过 `mod front_of_house;` 这条声明语句从该文件中把模块内容加载进来。因此我们可以认为,模块 `front_of_house` 的定义还是在 `src/lib.rs` 中,只不过模块的具体内容被移动到了 `src/front_of_house.rs` 文件中。 需要注意的是,和之前代码中 `mod front_of_house{..}` 的完整模块不同,现在的代码中,模块的声明和实现是分离的,实现是在单独的 `front_of_house.rs` 文件中,然后通过 `mod front_of_house;` 这条声明语句从该文件中把模块内容加载进来。因此我们可以认为,模块 `front_of_house` 的定义还是在 `src/lib.rs` 中,只不过模块的具体内容被移动到了 `src/front_of_house.rs` 文件中。
在这里出现了一个新的关键字 `use`,联想到其它章节我们见过的标准库引入 `use std::fmt;`,可以大致猜测,该关键字用来将外部模块中的项引入到当前作用域中来,这样无需冗长的父模块前缀即可调用:`hosting::add_to_waitlist();`,在下节中,我们将对 `use` 进行详细的讲解。 在这里出现了一个新的关键字 `use`,联想到其它章节我们见过的标准库引入 `use std::fmt;`,可以大致猜测,该关键字用来将外部模块中的项引入到当前作用域中来,这样无需冗长的父模块前缀即可调用:`hosting::add_to_waitlist();`,在下节中,我们将对 `use` 进行详细的讲解。
## 课后练习
> [Rust By Practice](https://zh.practice.rs/crate-module/module.html),支持代码在线编辑和运行,并提供详细的[习题解答](https://github.com/sunface/rust-by-practice/blob/master/solutions/crate-module/module.md)。

@ -465,3 +465,7 @@ fn main() {
// 试一试 ^ 取消此行的注释 // 试一试 ^ 取消此行的注释
} }
``` ```
## 课后练习
> [Rust By Practice](https://zh.practice.rs/crate-module/use-pub.html),支持代码在线编辑和运行,并提供详细的[习题解答](https://github.com/sunface/rust-by-practice/blob/master/solutions/crate-module/use-pub.md)。

@ -370,4 +370,4 @@ fn main() {
## 课后练习 ## 课后练习
> [Rust By Practice](https://zh.practice.rs/flow-control.html),支持代码在线编辑和运行,并提供详细的[习题解答](https://github.com/sunface/rust-by-practice)。 > [Rust By Practice](https://zh.practice.rs/flow-control.html),支持代码在线编辑和运行,并提供详细的[习题解答](https://github.com/sunface/rust-by-practice/blob/master/solutions/flow-control.md)。

@ -41,7 +41,7 @@ fn main() {
其中,`s1` 是通过 `format!` 生成的 `String` 字符串,最终输出如下: 其中,`s1` 是通过 `format!` 生成的 `String` 字符串,最终输出如下:
```console ```console
hello, wolrd hello, world
hello, world! hello, world!
``` ```
@ -457,6 +457,10 @@ thread 'main' panicked at 'Hello, sunface!', src/main.rs:6:5
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
``` ```
## 课后练习
> [Rust By Practice](https://zh.practice.rs/formatted-output.html),支持代码在线编辑和运行,并提供详细的习题解答。(本节暂无习题解答)
## 总结 ## 总结
把这些格式化都牢记在脑中是不太现实的,也没必要,我们要做的就是知道 Rust 支持相应的格式化输出,在需要之时,读者再来查阅本文即可。 把这些格式化都牢记在脑中是不太现实的,也没必要,我们要做的就是知道 Rust 支持相应的格式化输出,在需要之时,读者再来查阅本文即可。

@ -613,4 +613,4 @@ num @ (1 | 2)
## 课后练习 ## 课后练习
> [Rust By Practice](https://zh.practice.rs/pattern-match/patterns.html),支持代码在线编辑和运行,并提供详细的[习题解答](https://github.com/sunface/rust-by-practice)。 > [Rust By Practice](https://zh.practice.rs/pattern-match/patterns.html),支持代码在线编辑和运行,并提供详细的[习题解答](https://github.com/sunface/rust-by-practice/blob/master/solutions/pattern-match/patterns.md)。

@ -2,4 +2,4 @@
模式匹配,这个词,对于非函数语言编程来说,真的还蛮少听到,因为它经常出现在函数式编程里,用于为复杂的类型系统提供一个轻松的解构能力。 模式匹配,这个词,对于非函数语言编程来说,真的还蛮少听到,因为它经常出现在函数式编程里,用于为复杂的类型系统提供一个轻松的解构能力。
曾记否?在枚举和流程控制那章,我们遗留了两个问题,都是关于 `match` 的,第一个是如何对 `Option` 枚举进行进一步处理,另外一个是如何用 `match` 来替代 `else if` 这种丑陋的多重分支使用方式那么让我们先一起来揭开 `match` 的神秘面纱。 曾记否?在枚举和流程控制那章,我们遗留了两个问题,都是关于 `match` 的,第一个是如何对 `Option` 枚举进行进一步处理,另外一个是如何用 `match` 来替代 `else if` 这种丑陋的多重分支使用方式那么让我们先一起来揭开 `match` 的神秘面纱。

@ -240,7 +240,7 @@ error[E0004]: non-exhaustive patterns: `West` not covered // 非穷尽匹配,`
#### `_` 通配符 #### `_` 通配符
当我们不想在匹配列出所有值的时候,可以使用 Rust 提供的一个特殊**模式**,例如,`u8` 可以拥有 0 到 255 的有效的值,但是我们只关心 `1、3、5 和 7` 这几个值,不想列出其它的 `0、2、4、6、8、9 一直到 255` 的值。那么, 我们不必一个一个列出所有值, 因为可以使用特殊的模式 `_` 替代: 当我们不想在匹配时列出所有值的时候,可以使用 Rust 提供的一个特殊**模式**,例如,`u8` 可以拥有 0 到 255 的有效的值,但是我们只关心 `1、3、5 和 7` 这几个值,不想列出其它的 `0、2、4、6、8、9 一直到 255` 的值。那么, 我们不必一个一个列出所有值, 因为可以使用特殊的模式 `_` 替代:
```rust ```rust
let some_u8_value = 0u8; let some_u8_value = 0u8;
@ -255,7 +255,7 @@ match some_u8_value {
通过将 `_` 其放置于其他分支后,`_` 将会匹配所有遗漏的值。`()` 表示返回**单元类型**与所有分支返回值的类型相同,所以当匹配到 `_` 后,什么也不会发生。 通过将 `_` 其放置于其他分支后,`_` 将会匹配所有遗漏的值。`()` 表示返回**单元类型**与所有分支返回值的类型相同,所以当匹配到 `_` 后,什么也不会发生。
,在某些场景下,我们其实只关心**某一个值是否存在**,此时 `match` 就显得过于啰嗦。 ,在某些场景下,我们其实只关心**某一个值是否存在**,此时 `match` 就显得过于啰嗦。
## `if let` 匹配 ## `if let` 匹配
@ -271,7 +271,7 @@ match some_u8_value {
我们只想要对 `Some(3)` 模式进行匹配, 不想处理任何其他 `Some<u8>` 值或 `None` 值。但是为了满足 `match` 表达式(穷尽性)的要求,写代码时必须在处理完这唯一的成员后加上 `_ => ()`,这样会增加不少无用的代码。 我们只想要对 `Some(3)` 模式进行匹配, 不想处理任何其他 `Some<u8>` 值或 `None` 值。但是为了满足 `match` 表达式(穷尽性)的要求,写代码时必须在处理完这唯一的成员后加上 `_ => ()`,这样会增加不少无用的代码。
杀鸡焉用牛刀,可以用 `if let` 的方式来实现: 俗话说“杀鸡焉用牛刀我们完全可以用 `if let` 的方式来实现:
```rust ```rust
if let Some(3) = v { if let Some(3) = v {
@ -365,4 +365,4 @@ fn main() {
## 课后练习 ## 课后练习
> [Rust By Practice](https://zh.practice.rs/pattern-match/match-iflet.html),支持代码在线编辑和运行,并提供详细的[习题解答](https://github.com/sunface/rust-by-practice)。 > [Rust By Practice](https://zh.practice.rs/pattern-match/match-iflet.html),支持代码在线编辑和运行,并提供详细的[习题解答](https://github.com/sunface/rust-by-practice/blob/master/solutions/pattern-match/match.md)。

@ -155,7 +155,7 @@ let Some(x) = some_option_value;
因为右边的值可能不为 `Some`,而是 `None`,这种时候就不能进行匹配,也就是上面的代码遗漏了 `None` 的匹配。 因为右边的值可能不为 `Some`,而是 `None`,这种时候就不能进行匹配,也就是上面的代码遗漏了 `None` 的匹配。
类似 `let` `for``match` 都必须要求完全覆盖匹配,才能通过编译( 不可驳模式匹配 )。 类似 `let` , `for``match` 都必须要求完全覆盖匹配,才能通过编译( 不可驳模式匹配 )。
但是对于 `if let`,就可以这样使用: 但是对于 `if let`,就可以这样使用:

@ -279,4 +279,4 @@ fn main() {
## 课后练习 ## 课后练习
> [Rust By Practice](https://zh.practice.rs/method.html),支持代码在线编辑和运行,并提供详细的[习题解答](https://github.com/sunface/rust-by-practice)。 > [Rust By Practice](https://zh.practice.rs/method.html),支持代码在线编辑和运行,并提供详细的[习题解答](https://github.com/sunface/rust-by-practice/blob/master/solutions/method.md)。

@ -312,4 +312,4 @@ fn no_dangle() -> String {
## 课后练习 ## 课后练习
> [Rust By Practice](https://zh.practice.rs/ownership/borrowing.html),支持代码在线编辑和运行,并提供详细的[习题解答](https://github.com/sunface/rust-by-practice)。 > [Rust By Practice](https://zh.practice.rs/ownership/borrowing.html),支持代码在线编辑和运行,并提供详细的[习题解答](https://github.com/sunface/rust-by-practice/blob/master/solutions/ownership/borrowing.md)。

@ -332,5 +332,5 @@ fn takes_and_gives_back(a_string: String) -> String { // a_string 进入作用
## 课后练习 ## 课后练习
> [Rust By Practice](https://zh.practice.rs/ownership/ownership.html),支持代码在线编辑和运行,并提供详细的[习题解答](https://github.com/sunface/rust-by-practice)。 > [Rust By Practice](https://zh.practice.rs/ownership/ownership.html),支持代码在线编辑和运行,并提供详细的[习题解答](https://github.com/sunface/rust-by-practice/blob/master/solutions/ownership/ownership.md)。

@ -427,4 +427,4 @@ fn main() {
## 课后练习 ## 课后练习
> [Rust By Practice](https://zh.practice.rs/generics-traits/advanced-traits.html),支持代码在线编辑和运行,并提供详细的[习题解答](https://github.com/sunface/rust-by-practice)。 > [Rust By Practice](https://zh.practice.rs/generics-traits/advanced-traits.html),支持代码在线编辑和运行,并提供详细的[习题解答](https://github.com/sunface/rust-by-practice/blob/master/solutions/generics-traits/advanced-trait.md)。

@ -180,7 +180,7 @@ error[E0308]: mismatched types //类型不匹配
当把 `1` 赋值给 `x` 时,变量 `p``T` 类型就被确定为整数类型,因此 `y` 也必须是整数类型,但是我们却给它赋予了浮点数,因此导致报错。 当把 `1` 赋值给 `x` 时,变量 `p``T` 类型就被确定为整数类型,因此 `y` 也必须是整数类型,但是我们却给它赋予了浮点数,因此导致报错。
如果想让 `x``y` 即能类型相同,又能类型不同,需要使用不同的泛型参数: 如果想让 `x``y` 既能类型相同,又能类型不同,就需要使用不同的泛型参数:
```rust ```rust
struct Point<T,U> { struct Point<T,U> {
@ -466,6 +466,8 @@ fn main() {
## 课后练习 ## 课后练习
> Rust By Practice支持代码在线编辑和运行并提供详细的[习题解答](https://github.com/sunface/rust-by-practice) > Rust By Practice支持代码在线编辑和运行并提供详细的习题解答。
> - [泛型](https://zh.practice.rs/generics-traits/generics.html) > - [泛型](https://zh.practice.rs/generics-traits/generics.html)
> - [习题解答](https://github.com/sunface/rust-by-practice/blob/master/solutions/generics-traits/generics.md)
> - [const 泛型](https://zh.practice.rs/generics-traits/const-generics.html) > - [const 泛型](https://zh.practice.rs/generics-traits/const-generics.html)
> - [习题解答](https://github.com/sunface/rust-by-practice/blob/master/solutions/generics-traits/const-generics.md)

@ -381,4 +381,4 @@ error[E0038]: the trait `std::clone::Clone` cannot be made into an object
## 课后练习 ## 课后练习
> [Rust By Practice](https://zh.practice.rs/generics-traits/trait-object.html),支持代码在线编辑和运行,并提供详细的[习题解答](https://github.com/sunface/rust-by-practice)。 > [Rust By Practice](https://zh.practice.rs/generics-traits/trait-object.html),支持代码在线编辑和运行,并提供详细的[习题解答](https://github.com/sunface/rust-by-practice/blob/master/solutions/generics-traits/trait-object.md)。

@ -4,7 +4,7 @@
要解决上述问题,需要把这些行为抽象出来,就要使用 Rust 中的特征 `trait` 概念。可能你是第一次听说这个名词,但是不要怕,如果学过其他语言,那么大概率你听说过接口,没错,特征很类似接口。 要解决上述问题,需要把这些行为抽象出来,就要使用 Rust 中的特征 `trait` 概念。可能你是第一次听说这个名词,但是不要怕,如果学过其他语言,那么大概率你听说过接口,没错,特征很类似接口。
在之前的代码中,我们也多次见过特征的使用,例如 `#[derive(Debug)]`,它在我们定义的类型`struct`上自动派生 `Debug` 特征,接着可以使用 `println!("{:?}", x)` 打印这个类型;再例如: 在之前的代码中,我们也多次见过特征的使用,例如 `#[derive(Debug)]`,它在我们定义的类型(`struct`)上自动派生 `Debug` 特征,接着可以使用 `println!("{:?}", x)` 打印这个类型;再例如:
```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 {
@ -580,4 +580,4 @@ fn main() {
## 课后练习 ## 课后练习
> [Rust By Practice](https://zh.practice.rs/generics-traits/traits.html),支持代码在线编辑和运行,并提供详细的[习题解答](https://github.com/sunface/rust-by-practice)。 > [Rust By Practice](https://zh.practice.rs/generics-traits/traits.html),支持代码在线编辑和运行,并提供详细的[习题解答](https://github.com/sunface/rust-by-practice/blob/master/solutions/generics-traits/traits.md)。

@ -259,5 +259,5 @@ error: aborting due to previous error
## 课后练习 ## 课后练习
> [Rust By Practice](https://zh.practice.rs/variables.html),支持代码在线编辑和运行,并提供详细的[习题解答](https://github.com/sunface/rust-by-practice)。 > [Rust By Practice](https://zh.practice.rs/variables.html),支持代码在线编辑和运行,并提供详细的[习题解答](https://github.com/sunface/rust-by-practice/blob/master/solutions/variables.md)。

Loading…
Cancel
Save