mirror of
https://github.com/gnu4cn/rust-lang-zh_CN.git
synced 2025-02-04 08:30:14 +08:00
Initial commit.
This commit is contained in:
commit
cf2b9a266c
2
.gitignore
vendored
Normal file
2
.gitignore
vendored
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
book
|
||||||
|
target
|
91
README.md
Normal file
91
README.md
Normal file
@ -0,0 +1,91 @@
|
|||||||
|
# Rust 编程语言
|
||||||
|
|
||||||
|
|
||||||
|
原著:[The Rust Programming Language](https://doc.rust-lang.org/book/)
|
||||||
|
|
||||||
|
*原作者:Steve Klabnik 与 Carol Nichols, 及 Rust 社区*
|
||||||
|
|
||||||
|
|
||||||
|
此版本的教材,假定安装了 Rust `1.67.1` (发布于 2023-02-09)或更新版本。请参阅 [第 1 章的 “安装” 小节](docs/Ch01_Getting_Started.md#Installation) 进行安装,或对已安装的 Rust 进行升级。
|
||||||
|
|
||||||
|
```console
|
||||||
|
$ rustc --version
|
||||||
|
rustc 1.68.0 (2c8cc3432 2023-03-06)
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
## 在线阅读
|
||||||
|
|
||||||
|
- [rust-lang.xfoss.com](https://rust-lang.xfoss.com)
|
||||||
|
|
||||||
|
- 在 Gitbook 上可阅读此教程:[Rust 编程语言](https://rust.xfoss.com)
|
||||||
|
|
||||||
|
## 简介
|
||||||
|
|
||||||
|
欢迎来到 *Rust 编程语言*,一本 Rust 的介绍性书籍。Rust 编程语言帮助更快地编写出更可靠软件。在程序语言设计中,上层人机交互与底层控制,通常是不可调和的;Rust 挑战了这对矛盾。经由强力的技术能力与了不起的开发者体验,Rust 带来了对底层细节(譬如内存的使用)控制的同时,免去了传统上底层控制带来的一大堆麻烦。
|
||||||
|
|
||||||
|
## Rust 适用于哪些人群
|
||||||
|
|
||||||
|
对于相当多的人群,Rust 因为各种原因,都是理想选择。下面就来看看那些最重要群体中的一些人的情况。
|
||||||
|
|
||||||
|
### 开发者团队
|
||||||
|
|
||||||
|
对于有着不同水平系统编程知识的开发者团队的协同来讲,Rust 正被证明是一种生产力工具。底层代码倾向于出现各种细微错误,这样的细微错误,对于其他编程语言,则只能经由广泛测试,和经验老道的开发者细致代码评审才能捕获到。而在 Rust 中,编译器通过拒绝编译这些难以捉摸的错误,包括并发错误,而扮演着看门人角色。通过与编译器一道工作,团队就可以将他们的时间,集中用在程序逻辑,而不是找寻错误上。
|
||||||
|
|
||||||
|
Rust 还带给了系统编程世界,一些现代开发者工具:
|
||||||
|
|
||||||
|
- `Cargo`,Rust 所包含的依赖管理器与构建工具,让整个 Rust 生态中添加依赖、编译与管理依赖,变得愉快并具一致性(`Cargo`, the included dependency manager and build tool, makes adding, compiling, and managing dependecies painless and consistant across the Rust ecosystem);
|
||||||
|
- `Rustfmt` 确保了不同开发者之间有着一致的编码风格;
|
||||||
|
- Rust 语言服务器驱动了用于代码补全与行内错误消息的集成开发环境。
|
||||||
|
|
||||||
|
通过使用这些开发者工具,及其他一些 Rust 生态中的工具,开发者就可以在编写系统级代码时,颇具生产力了。
|
||||||
|
|
||||||
|
### 学生
|
||||||
|
|
||||||
|
Rust 是为学生及那些对掌握系统概念感兴趣的人所准备的。运用 Rust,许多人都掌握了像是操作系统开发这样的知识点。Rust 社区非常欢迎并乐于回答学生们提出的问题。通过像是本书这样的努力,Rust 团队本身是要让更多人,尤其是那些刚开始编程的人们,可获取到系统概念。
|
||||||
|
|
||||||
|
|
||||||
|
### 商业公司
|
||||||
|
|
||||||
|
已有上千家规模或大或小的商业公司,在生产中,为着不同任务使用着 Rust。这些任务包括了命令行工具、web 服务、运维工具、嵌入式装置、音视频分析与转码、加密货币、生物信息学、搜索引擎、物联网应用、机器学习,甚至Firefox web浏览器的主要部分等等。
|
||||||
|
|
||||||
|
### 开放源代码开发者
|
||||||
|
|
||||||
|
Rust 是为着那些想要构建 Rust 编程语言本身、Rust 社区、Rust 开发者工具和库而准备的。我们希望你为 Rust 语言做出贡献。
|
||||||
|
|
||||||
|
### 看重运行速度与稳定性的人们
|
||||||
|
|
||||||
|
Rust 是为那些渴求某门语言所提供速度与稳定性的人们准备的。这里说的运行速度,指的是使用 Rust 可创建出程序的运行速度,以及 Rust 所能达到的编写这些程序速度。Rust 编译器的检查,确保了功能补充与重构的稳定性。这稳定性是与那些不具备这些检查语言中的脆弱老旧代码相比得出的,开发者通常害怕去修改那些脆弱老旧代码。通过争取实现零代价的抽象,就有了那些在手动编写时,就立即编译到底层代码的上层特性,Rust 致力于实现在构造安全代码的同时,还取得了快速的代码编写与程序运行。
|
||||||
|
|
||||||
|
Rust 语言也希望带给众多其他用户以支持;这里提到的只是一些最大的相关群体。总体来讲,Rust 最伟大的抱负,是要消除程序员们在过去数十年来,业已被迫接受的在安全性与生产力、开发和运行速度及人机交互上的妥协。请给 Rust 一个机会,然后看看 Rust 的选择是否适合于你。
|
||||||
|
|
||||||
|
## 本书读者群体
|
||||||
|
|
||||||
|
本书假定你曾编写过其他某种编程语言的代码,至于何种编程语言并不重要。本书作者已尽力让其中的教学材料适合到有着宽泛编程背景的读者。这里不会花大量时间来解释编程为何物,以及该怎么来看待编程。若对编程一窍不通,那么最好找一本编程入门的书先看看。
|
||||||
|
|
||||||
|
## 怎样使用本书
|
||||||
|
|
||||||
|
大体上,本书假定是要以从前往后的顺序进行阅读。后续章节是建立在较早章节的概念之上,而较早的章节不会深入某个话题的细节;在后续章节通常会回顾到那个话题。
|
||||||
|
|
||||||
|
本书有两种章节:概念性章节与项目性章节。在概念章节,将对 Rust 某个方面的有所了解。而在项目性章节,就会构建出一些在一起的小程序,这些小程序运用了概念性章节中学到的东西。第 2、12 和 20 章,就是项目性章节;而剩下的,全都是概念性章节。
|
||||||
|
|
||||||
|
第 1 章讲了怎样安装 Rust、怎样编写出 “Hello, world!” 程序,还有怎样使用 Rust 的包管理器及构建工具 `Cargo`。第 2 章是 Rust 语言的一个实操介绍。这里涵盖了上层的一些概念,而在后续章节则会提供到进一步的细节。若要立即动手编写代码,那么第 2 章就可以开始了。一开始你或许想要跳过第 3 章,这一章涵盖了与那些其他编程语言类似的一些 Rust 特性,而要直接前往到第 4 章,去了解 Rust 的所有权系统。不过若要细致了解 Rust,就应详细掌握 Rust 的每个细节设计之后,在移步到下一章节,或许也会跳过第 2 章直接到第 3 章,然后在想要将学到的细节知识应用到项目时,再回到第 2 章。
|
||||||
|
|
||||||
|
第 5 章讨论了结构体和方法,同时第 6 章涵盖了枚举、`match` 表达式,和 `if let` 控制流结构。在构造 Rust 中的定制类型时,就会用到这些结构体和枚举。
|
||||||
|
|
||||||
|
第 7 章将了解到 Rust 的模组系统,以及代码组织的隐私规则,还有 Rust 的公共应用编程接口(Application Programming Interface, API)。第 8 章讨论了一些常用的、由标准库提供的集合数据结构,诸如矢量、字符串及哈希图。第 9 章探索了 Rust 的错误处理思想与技巧。
|
||||||
|
|
||||||
|
第 10 章涉及了范型、特质(traits) 与生命周期,他们赋予了定义出应用多种类型代码的能力。第 11 章全都是关于测试的内容,即便有着 Rust 的安全性保证,对于确保程序逻辑正确,测试仍是不可缺少的。第 12 章将构建一个我们自己的、用于在文件中搜索文本的 `grep` 命令行工具功能子集的版本。到这里,就会用到先前章节中所讨论的众多概念了。
|
||||||
|
|
||||||
|
第 13 章对闭包(closures)和迭代进行了探索:闭包和迭代属于 Rust 来自函数式编程语言的特性。第 14 章,将更深入地对 `Cargo` 加以检视,并就如何与他人分享库的最佳实践进行探讨。第 15 章讨论标准库提供的一些灵巧指针,还有实现不同功能的 Rust 特质(traits)。
|
||||||
|
|
||||||
|
第 16 章,将遍数并发编程的各种不同模型,并探讨 Rust 如何对大胆进行多线程编程的帮助。第 17 章将或许你所熟知面向对象编程的那些原则,与 Rust 下编程的习惯加以对比。
|
||||||
|
|
||||||
|
第 18 章是模式与模式匹配的一个参考,这在 Rust 程序中,属于是概念表达的强大方式。第 19 章包含了一个诸多感兴趣的话题大杂烩,包括不安全的 Rust、宏,以及更多有关生命周期、特质(traits)、类型、函数与闭包等等的细节。
|
||||||
|
|
||||||
|
第 20 章,将完成一个其中实现了底层线程化的 web 服务器!
|
||||||
|
|
||||||
|
最后,还有一些包含了这门语言的有用信息的附录,这些附录则更多的像是参考的形式。附录 A 涵盖了 Rust 的关键字,附录 B 涵盖了 Rust 的运算符和符号,附录 C 涵盖了由标准库所提供的那些派生特质(derivable traits),附录 D 涵盖了一些有用的开发工具,还有附录 E 对 Rust 版本进行了解释。
|
||||||
|
|
||||||
|
阅读本书并无定法:你要跳着去读,也是可以的!在遇到疑惑时,或许就不得不跳回去看看了。你只要怎么有效就行了。
|
||||||
|
|
6
add/Cargo.toml
Normal file
6
add/Cargo.toml
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
[workspace]
|
||||||
|
|
||||||
|
members = [
|
||||||
|
"adder",
|
||||||
|
"add_one",
|
||||||
|
]
|
9
add/add_one/Cargo.toml
Normal file
9
add/add_one/Cargo.toml
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
[package]
|
||||||
|
name = "add_one"
|
||||||
|
version = "0.1.0"
|
||||||
|
edition = "2021"
|
||||||
|
|
||||||
|
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||||
|
|
||||||
|
[dependencies]
|
||||||
|
rand = "^0.8.4"
|
14
add/add_one/src/lib.rs
Normal file
14
add/add_one/src/lib.rs
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
pub fn add_one(x: i32) -> i32 {
|
||||||
|
x + 1
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod tests {
|
||||||
|
use super::*;
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn it_works() {
|
||||||
|
let result = add_one(2);
|
||||||
|
assert_eq!(result, 3);
|
||||||
|
}
|
||||||
|
}
|
10
add/adder/Cargo.toml
Normal file
10
add/adder/Cargo.toml
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
[package]
|
||||||
|
name = "adder"
|
||||||
|
version = "0.1.0"
|
||||||
|
edition = "2021"
|
||||||
|
|
||||||
|
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||||
|
|
||||||
|
[dependencies]
|
||||||
|
add_one = { path = "../add_one" }
|
||||||
|
rand = "0.8.4"
|
6
add/adder/src/main.rs
Normal file
6
add/adder/src/main.rs
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
use add_one::add_one;
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
let num = 10;
|
||||||
|
println!("你好,世界!\n\t{num} 加 1 为 {}!", add_one(num));
|
||||||
|
}
|
8
adder/Cargo.toml
Normal file
8
adder/Cargo.toml
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
[package]
|
||||||
|
name = "adder"
|
||||||
|
version = "0.1.0"
|
||||||
|
edition = "2021"
|
||||||
|
|
||||||
|
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||||
|
|
||||||
|
[dependencies]
|
17
adder/src/lib.rs
Normal file
17
adder/src/lib.rs
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
pub fn add_two(a: i32) -> i32 {
|
||||||
|
internal_add(a, 2)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn internal_add(a: i32, b: i32) -> i32 {
|
||||||
|
a + b
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod tests {
|
||||||
|
use super::*;
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn internal() {
|
||||||
|
assert_eq! (4, internal_add(2, 2));
|
||||||
|
}
|
||||||
|
}
|
3
adder/tests/common/mod.rs
Normal file
3
adder/tests/common/mod.rs
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
pub fn setup() {
|
||||||
|
println! ("特定于库测试的一些设置代码,将放在这里");
|
||||||
|
}
|
9
adder/tests/integration_test.rs
Normal file
9
adder/tests/integration_test.rs
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
use adder;
|
||||||
|
|
||||||
|
mod common;
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn it_adds_two() {
|
||||||
|
common::setup();
|
||||||
|
assert_eq! (6, adder::add_two(4));
|
||||||
|
}
|
8
aggregator/Cargo.toml
Normal file
8
aggregator/Cargo.toml
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
[package]
|
||||||
|
name = "aggregator"
|
||||||
|
version = "0.1.0"
|
||||||
|
edition = "2021"
|
||||||
|
|
||||||
|
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||||
|
|
||||||
|
[dependencies]
|
3
aggregator/src/bin/test_case.rs
Normal file
3
aggregator/src/bin/test_case.rs
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
fn main() {
|
||||||
|
println! ("媒体聚合器");
|
||||||
|
}
|
56
aggregator/src/lib.rs
Normal file
56
aggregator/src/lib.rs
Normal file
@ -0,0 +1,56 @@
|
|||||||
|
pub trait Summary {
|
||||||
|
fn summarize_author(&self) -> String;
|
||||||
|
|
||||||
|
fn summarize(&self) -> String {
|
||||||
|
format! ("(了解更多来自 {} ......)", self.summarize_author())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct NewsArticle {
|
||||||
|
pub headline: String,
|
||||||
|
pub location: String,
|
||||||
|
pub author: String,
|
||||||
|
pub content: String,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Summary for NewsArticle {
|
||||||
|
fn summarize_author(&self) -> String {
|
||||||
|
format! ("{}", self.author)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct Tweet {
|
||||||
|
pub username: String,
|
||||||
|
pub content: String,
|
||||||
|
pub reply: bool,
|
||||||
|
pub retweet: bool,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Summary for Tweet {
|
||||||
|
fn summarize_author(&self) -> String {
|
||||||
|
format! ("@{}", self.username)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
use std::fmt::Display;
|
||||||
|
|
||||||
|
pub struct Pair<T> {
|
||||||
|
pub x: T,
|
||||||
|
pub y: T,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T> Pair<T> {
|
||||||
|
pub fn new(x: T, y: T) -> Self {
|
||||||
|
Self { x, y }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T: Display + PartialOrd> Pair<T> {
|
||||||
|
pub fn cmp_display(&self) {
|
||||||
|
if self.x >= self.y {
|
||||||
|
println! ("极大数为 x = {}", self.x);
|
||||||
|
} else {
|
||||||
|
println! ("极大数为 y = {}", self.y);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
54
aggregator/src/main.rs
Normal file
54
aggregator/src/main.rs
Normal file
@ -0,0 +1,54 @@
|
|||||||
|
use aggregator::{Summary, Tweet, NewsArticle, Pair};
|
||||||
|
|
||||||
|
pub fn notify<T: Summary>(item: &T) {
|
||||||
|
println! ("突发新闻!{}", item.summarize());
|
||||||
|
}
|
||||||
|
|
||||||
|
fn return_summarizable() -> impl Summary {
|
||||||
|
Tweet {
|
||||||
|
username: String::from("horse_ebooks"),
|
||||||
|
content: String::from(
|
||||||
|
"当然,如同你或许已经知道的一样,朋友们"
|
||||||
|
),
|
||||||
|
reply: false,
|
||||||
|
retweet: false,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
let tweet = Tweet {
|
||||||
|
username: String::from("horse_ebooks"),
|
||||||
|
content: String::from(
|
||||||
|
"当然,跟大家已经清楚的一样了,朋友们",
|
||||||
|
),
|
||||||
|
reply: false,
|
||||||
|
retweet: false,
|
||||||
|
};
|
||||||
|
|
||||||
|
println!("1 条新推文: {}", tweet.summarize());
|
||||||
|
notify(&tweet);
|
||||||
|
|
||||||
|
|
||||||
|
let article = NewsArticle {
|
||||||
|
headline: String::from("企鹅队赢得斯坦利杯锦标赛!"),
|
||||||
|
location: String::from("美国,宾夕法尼亚州,匹兹堡"),
|
||||||
|
author: String::from("Iceburgh"),
|
||||||
|
content: String::from(
|
||||||
|
"匹兹堡企鹅队再度成为美国曲棍球联盟 \
|
||||||
|
NHL 中的最佳球队。"
|
||||||
|
),
|
||||||
|
};
|
||||||
|
|
||||||
|
println! ("有新文章可读!{}", article.summarize());
|
||||||
|
notify(&article);
|
||||||
|
|
||||||
|
println! ("1 条旧推文: {}", return_summarizable().summarize());
|
||||||
|
|
||||||
|
let pair = Pair::new(5, 10);
|
||||||
|
pair.cmp_display();
|
||||||
|
|
||||||
|
let pair = Pair::new("这是一个测试", "This is a test.");
|
||||||
|
pair.cmp_display();
|
||||||
|
|
||||||
|
println! ("{}", 3.to_string());
|
||||||
|
}
|
8
art/Cargo.toml
Normal file
8
art/Cargo.toml
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
[package]
|
||||||
|
name = "art"
|
||||||
|
version = "0.1.0"
|
||||||
|
edition = "2021"
|
||||||
|
|
||||||
|
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||||
|
|
||||||
|
[dependencies]
|
15
art/src/kinds.rs
Normal file
15
art/src/kinds.rs
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
/// RYB 颜色模型下的主要颜色。
|
||||||
|
#[derive(Debug)]
|
||||||
|
pub enum PrimaryColor {
|
||||||
|
Red,
|
||||||
|
Yellow,
|
||||||
|
Blue,
|
||||||
|
}
|
||||||
|
|
||||||
|
/// RYB 颜色模型下的次要颜色。
|
||||||
|
#[derive(Debug)]
|
||||||
|
pub enum SecondaryColor {
|
||||||
|
Orange,
|
||||||
|
Green,
|
||||||
|
Purple,
|
||||||
|
}
|
10
art/src/lib.rs
Normal file
10
art/src/lib.rs
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
//! # art - 美术
|
||||||
|
//!
|
||||||
|
//! 建模诸多美术概念的一个库。
|
||||||
|
|
||||||
|
pub mod kinds;
|
||||||
|
pub mod utils;
|
||||||
|
|
||||||
|
pub use self::kinds::PrimaryColor;
|
||||||
|
pub use self::kinds::SecondaryColor;
|
||||||
|
pub use self::utils::mix;
|
9
art/src/utils.rs
Normal file
9
art/src/utils.rs
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
use crate::kinds::*;
|
||||||
|
|
||||||
|
/// 结合两种等量的主要颜色,创建出
|
||||||
|
/// 某种次要颜色。
|
||||||
|
pub fn mix(c1: PrimaryColor, c2: PrimaryColor) -> SecondaryColor {
|
||||||
|
// --跳过代码--
|
||||||
|
println! ("c1: {:?}, c2: {:?}", c1, c2);
|
||||||
|
SecondaryColor::Purple
|
||||||
|
}
|
8
assert_demo/Cargo.toml
Normal file
8
assert_demo/Cargo.toml
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
[package]
|
||||||
|
name = "assert_demo"
|
||||||
|
version = "0.1.0"
|
||||||
|
edition = "2021"
|
||||||
|
|
||||||
|
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||||
|
|
||||||
|
[dependencies]
|
43
assert_demo/src/lib.rs
Normal file
43
assert_demo/src/lib.rs
Normal file
@ -0,0 +1,43 @@
|
|||||||
|
pub fn add_two(a: i32) -> i32 {
|
||||||
|
a + 2
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn nth_fibonacci(n: u64) -> u64 {
|
||||||
|
|
||||||
|
if n == 0 || n == 1 {
|
||||||
|
return n;
|
||||||
|
} else {
|
||||||
|
return nth_fibonacci(n - 1) + nth_fibonacci(n - 2);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod tests {
|
||||||
|
use super::*;
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn add_two_and_two() {
|
||||||
|
assert_eq! (4, add_two(2));
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn add_three_and_two() {
|
||||||
|
assert_eq! (5, add_two(3));
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn one_hundred() {
|
||||||
|
assert_eq! (102, add_two(100));
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn it_works() {
|
||||||
|
assert_eq! (2 + 2, 4);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
#[ignore]
|
||||||
|
fn expensive_test() {
|
||||||
|
assert_ne! (100, nth_fibonacci(50));
|
||||||
|
}
|
||||||
|
}
|
7
associated_type/Cargo.lock
generated
Normal file
7
associated_type/Cargo.lock
generated
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
# This file is automatically @generated by Cargo.
|
||||||
|
# It is not intended for manual editing.
|
||||||
|
version = 3
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "associated_type"
|
||||||
|
version = "0.1.0"
|
8
associated_type/Cargo.toml
Normal file
8
associated_type/Cargo.toml
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
[package]
|
||||||
|
name = "associated_type"
|
||||||
|
version = "0.1.0"
|
||||||
|
edition = "2021"
|
||||||
|
|
||||||
|
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||||
|
|
||||||
|
[dependencies]
|
3
associated_type/src/main.rs
Normal file
3
associated_type/src/main.rs
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
fn main() {
|
||||||
|
println!("Hello, world!");
|
||||||
|
}
|
6
book.toml
Normal file
6
book.toml
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
[book]
|
||||||
|
authors = ["Lenny Peng"]
|
||||||
|
language = "zh_CN"
|
||||||
|
multilingual = false
|
||||||
|
src = "src"
|
||||||
|
title = "Yet another Chinese rust-lang book."
|
8
branches/Cargo.toml
Normal file
8
branches/Cargo.toml
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
[package]
|
||||||
|
name = "branches"
|
||||||
|
version = "0.1.0"
|
||||||
|
edition = "2021"
|
||||||
|
|
||||||
|
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||||
|
|
||||||
|
[dependencies]
|
7
branches/src/main.rs
Normal file
7
branches/src/main.rs
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
fn main() {
|
||||||
|
let condition = true;
|
||||||
|
|
||||||
|
let number = if condition { 5 } else { "six" };
|
||||||
|
|
||||||
|
println! ("number 的值为:{}", number);
|
||||||
|
}
|
9
cargo_features_demo/Cargo.toml
Normal file
9
cargo_features_demo/Cargo.toml
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
[package]
|
||||||
|
name = "cargo_features_demo"
|
||||||
|
version = "0.1.0"
|
||||||
|
edition = "2021"
|
||||||
|
|
||||||
|
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||||
|
|
||||||
|
[dependencies]
|
||||||
|
art = { path = "../art" }
|
21
cargo_features_demo/src/lib.rs
Normal file
21
cargo_features_demo/src/lib.rs
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
//! # Cargo 特性示例代码箱
|
||||||
|
//!
|
||||||
|
//! `cargo_features_demo` 是令到执行某些确切计算更便利
|
||||||
|
//! 的一些工具的集合。
|
||||||
|
//!
|
||||||
|
|
||||||
|
/// 将一加到所给数字。
|
||||||
|
/// # 示例(examples)
|
||||||
|
///
|
||||||
|
/// ```
|
||||||
|
/// let arg = 5;
|
||||||
|
/// let answer = cargo_features_demo::add_one(arg);
|
||||||
|
///
|
||||||
|
/// assert_eq! (6, answer);
|
||||||
|
/// ```
|
||||||
|
pub fn add_one(x: i32) -> i32 {
|
||||||
|
x + 2
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod tests;
|
8
cargo_features_demo/src/main.rs
Normal file
8
cargo_features_demo/src/main.rs
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
use art::mix;
|
||||||
|
use art::PrimaryColor;
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
let red = PrimaryColor::Red;
|
||||||
|
let yellow = PrimaryColor::Yellow;
|
||||||
|
mix(red, yellow);
|
||||||
|
}
|
6
cargo_features_demo/src/tests.rs
Normal file
6
cargo_features_demo/src/tests.rs
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
use super::*;
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn five_plus_one() {
|
||||||
|
assert_eq! (7, add_one(5));
|
||||||
|
}
|
8
closure-example/Cargo.toml
Normal file
8
closure-example/Cargo.toml
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
[package]
|
||||||
|
name = "closure-example"
|
||||||
|
version = "0.1.0"
|
||||||
|
edition = "2021"
|
||||||
|
|
||||||
|
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||||
|
|
||||||
|
[dependencies]
|
22
closure-example/src/main.rs
Normal file
22
closure-example/src/main.rs
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
#[derive(Debug)]
|
||||||
|
struct Rectangle {
|
||||||
|
width: u32,
|
||||||
|
height: u32,
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
let mut list = [
|
||||||
|
Rectangle { width: 10, height: 1 },
|
||||||
|
Rectangle { width: 3, height: 5 },
|
||||||
|
Rectangle { width: 7, height: 12 },
|
||||||
|
];
|
||||||
|
|
||||||
|
let mut sort_operations = vec! [];
|
||||||
|
let value = String::from("按照被调用到的 key");
|
||||||
|
|
||||||
|
list.sort_by_key(|r| {
|
||||||
|
sort_operations.push(&value);
|
||||||
|
r.width
|
||||||
|
});
|
||||||
|
println! ("{:#?}\n{:#?}", list, sort_operations);
|
||||||
|
}
|
8
closure_demo/Cargo.toml
Normal file
8
closure_demo/Cargo.toml
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
[package]
|
||||||
|
name = "closure_demo"
|
||||||
|
version = "0.1.0"
|
||||||
|
edition = "2021"
|
||||||
|
|
||||||
|
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||||
|
|
||||||
|
[dependencies]
|
57
closure_demo/src/main.rs
Normal file
57
closure_demo/src/main.rs
Normal file
@ -0,0 +1,57 @@
|
|||||||
|
#[derive(Debug, PartialEq, Copy, Clone)]
|
||||||
|
enum ShirtColor {
|
||||||
|
Red,
|
||||||
|
Blue,
|
||||||
|
}
|
||||||
|
|
||||||
|
struct Inventory {
|
||||||
|
shirts: Vec<ShirtColor>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Inventory {
|
||||||
|
fn giveaway(
|
||||||
|
&self,
|
||||||
|
user_preference: Option<ShirtColor>
|
||||||
|
) -> ShirtColor {
|
||||||
|
user_preference.unwrap_or_else(|| self.most_stocked())
|
||||||
|
}
|
||||||
|
|
||||||
|
fn most_stocked(&self) -> ShirtColor {
|
||||||
|
let mut num_red = 0;
|
||||||
|
let mut num_blue = 0;
|
||||||
|
|
||||||
|
for color in &self.shirts {
|
||||||
|
match color {
|
||||||
|
ShirtColor::Red => num_red += 1,
|
||||||
|
ShirtColor::Blue => num_blue += 1,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if num_red > num_blue {
|
||||||
|
ShirtColor::Red
|
||||||
|
} else {
|
||||||
|
ShirtColor::Blue
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
let store = Inventory {
|
||||||
|
shirts: vec! [ShirtColor::Blue, ShirtColor::Red, ShirtColor::Blue],
|
||||||
|
};
|
||||||
|
|
||||||
|
let user_pref1 = Some(ShirtColor::Red);
|
||||||
|
let giveaway1 = store.giveaway(user_pref1);
|
||||||
|
println! (
|
||||||
|
"选项为 {:?} 的用户,得到了 {:?}",
|
||||||
|
user_pref1, giveaway1
|
||||||
|
);
|
||||||
|
|
||||||
|
let user_pref2 = None;
|
||||||
|
let giveaway2 = store.giveaway(user_pref2);
|
||||||
|
println! (
|
||||||
|
"选项为 {:?} 的用户得到了 {:?}",
|
||||||
|
user_pref2, giveaway2
|
||||||
|
);
|
||||||
|
|
||||||
|
}
|
8
concur_demo/Cargo.toml
Normal file
8
concur_demo/Cargo.toml
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
[package]
|
||||||
|
name = "concur_demo"
|
||||||
|
version = "0.1.0"
|
||||||
|
edition = "2021"
|
||||||
|
|
||||||
|
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||||
|
|
||||||
|
[dependencies]
|
14
concur_demo/src/main.rs
Normal file
14
concur_demo/src/main.rs
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
#![allow(dead_code)]
|
||||||
|
#![allow(unused_variables)]
|
||||||
|
|
||||||
|
use std::thread;
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
let v = vec! [1, 2, 3];
|
||||||
|
|
||||||
|
let handle = thread::spawn(move || {
|
||||||
|
println! ("这里有个矢量值:{:?}", &v);
|
||||||
|
});
|
||||||
|
|
||||||
|
handle.join().unwrap();
|
||||||
|
}
|
8
cons_list_demo/Cargo.toml
Normal file
8
cons_list_demo/Cargo.toml
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
[package]
|
||||||
|
name = "cons_list_demo"
|
||||||
|
version = "0.1.0"
|
||||||
|
edition = "2021"
|
||||||
|
|
||||||
|
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||||
|
|
||||||
|
[dependencies]
|
24
cons_list_demo/src/main.rs
Normal file
24
cons_list_demo/src/main.rs
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
#[derive(Debug)]
|
||||||
|
enum List {
|
||||||
|
Cons(Rc<RefCell<i32>>, Rc<List>),
|
||||||
|
Nil,
|
||||||
|
}
|
||||||
|
|
||||||
|
use crate::List::{Cons, Nil};
|
||||||
|
use std::cell::RefCell;
|
||||||
|
use std::rc::Rc;
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
let value = Rc::new(RefCell::new(5));
|
||||||
|
|
||||||
|
let a = Rc::new(Cons(Rc::clone(&value), Rc::new(Nil)));
|
||||||
|
|
||||||
|
let b = Cons(Rc::new(RefCell::new(3)), Rc::clone(&a));
|
||||||
|
let c = Cons(Rc::new(RefCell::new(4)), Rc::clone(&a));
|
||||||
|
|
||||||
|
*value.borrow_mut() += 10;
|
||||||
|
|
||||||
|
println! ("之后的 a = {:?}", a);
|
||||||
|
println! ("之后的 b = {:?}", b);
|
||||||
|
println! ("之后的 c = {:?}", c);
|
||||||
|
}
|
7
declarative_macro/Cargo.lock
generated
Normal file
7
declarative_macro/Cargo.lock
generated
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
# This file is automatically @generated by Cargo.
|
||||||
|
# It is not intended for manual editing.
|
||||||
|
version = 3
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "declarative_macro"
|
||||||
|
version = "0.1.0"
|
8
declarative_macro/Cargo.toml
Normal file
8
declarative_macro/Cargo.toml
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
[package]
|
||||||
|
name = "declarative_macro"
|
||||||
|
version = "0.1.0"
|
||||||
|
edition = "2021"
|
||||||
|
|
||||||
|
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||||
|
|
||||||
|
[dependencies]
|
4
declarative_macro/src/main.rs
Normal file
4
declarative_macro/src/main.rs
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
fn main() {
|
||||||
|
|
||||||
|
println!("Hello, world!");
|
||||||
|
}
|
10
derive_macro_comsumer/Cargo.toml
Normal file
10
derive_macro_comsumer/Cargo.toml
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
[package]
|
||||||
|
name = "derive_macro_comsumer"
|
||||||
|
version = "0.1.0"
|
||||||
|
edition = "2021"
|
||||||
|
|
||||||
|
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||||
|
|
||||||
|
[dependencies]
|
||||||
|
hello_macro = { path = "../hello_macro" }
|
||||||
|
hello_macro_derive = { path = "../hello_macro/hello_macro_derive" }
|
9
derive_macro_comsumer/src/main.rs
Normal file
9
derive_macro_comsumer/src/main.rs
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
use hello_macro::HelloMacro;
|
||||||
|
use hello_macro_derive::HelloMacro;
|
||||||
|
|
||||||
|
#[derive(HelloMacro)]
|
||||||
|
struct Pancakes;
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
Pancakes::hello_macro();
|
||||||
|
}
|
8
disambiguation/Cargo.toml
Normal file
8
disambiguation/Cargo.toml
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
[package]
|
||||||
|
name = "disambiguation"
|
||||||
|
version = "0.1.0"
|
||||||
|
edition = "2021"
|
||||||
|
|
||||||
|
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||||
|
|
||||||
|
[dependencies]
|
21
disambiguation/src/main.rs
Normal file
21
disambiguation/src/main.rs
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
trait Animal {
|
||||||
|
fn baby_name() -> String;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct Dog;
|
||||||
|
|
||||||
|
impl Dog {
|
||||||
|
fn baby_name() -> String {
|
||||||
|
String::from("点点")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Animal for Dog {
|
||||||
|
fn baby_name() -> String {
|
||||||
|
String::from("狗崽")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
println! ("小狗叫做 {}", <Dog as Animal>::baby_name());
|
||||||
|
}
|
8
dst/Cargo.toml
Normal file
8
dst/Cargo.toml
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
[package]
|
||||||
|
name = "dst"
|
||||||
|
version = "0.1.0"
|
||||||
|
edition = "2021"
|
||||||
|
|
||||||
|
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||||
|
|
||||||
|
[dependencies]
|
4
dst/src/main.rs
Normal file
4
dst/src/main.rs
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
fn main() {
|
||||||
|
let s1: str = "致以问候!";
|
||||||
|
let s2: str = "最近过得怎么样?";
|
||||||
|
}
|
7
encapsulation_demo/Cargo.lock
generated
Normal file
7
encapsulation_demo/Cargo.lock
generated
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
# This file is automatically @generated by Cargo.
|
||||||
|
# It is not intended for manual editing.
|
||||||
|
version = 3
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "encapsulation_demo"
|
||||||
|
version = "0.1.0"
|
8
encapsulation_demo/Cargo.toml
Normal file
8
encapsulation_demo/Cargo.toml
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
[package]
|
||||||
|
name = "encapsulation_demo"
|
||||||
|
version = "0.1.0"
|
||||||
|
edition = "2021"
|
||||||
|
|
||||||
|
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||||
|
|
||||||
|
[dependencies]
|
34
encapsulation_demo/src/lib.rs
Normal file
34
encapsulation_demo/src/lib.rs
Normal file
@ -0,0 +1,34 @@
|
|||||||
|
#![allow(dead_code)]
|
||||||
|
#![allow(unused_variables)]
|
||||||
|
|
||||||
|
pub struct AveragedCollection {
|
||||||
|
list: Vec<i32>,
|
||||||
|
average: f64,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl AveragedCollection {
|
||||||
|
pub fn add(&mut self, value: i32) {
|
||||||
|
self.list.push(value);
|
||||||
|
self.update_average();
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn remove(&mut self) -> Option<i32> {
|
||||||
|
let result = self.list.pop();
|
||||||
|
match result {
|
||||||
|
Some(value) => {
|
||||||
|
self.update_average();
|
||||||
|
Some(value)
|
||||||
|
}
|
||||||
|
None => None,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn average(&self) -> f64 {
|
||||||
|
self.average
|
||||||
|
}
|
||||||
|
|
||||||
|
fn update_average(&mut self) {
|
||||||
|
let total: i32 = self.list.iter().sum();
|
||||||
|
self.average = total as f64 / self.list.len() as f64;
|
||||||
|
}
|
||||||
|
}
|
8
enum_demo/Cargo.toml
Normal file
8
enum_demo/Cargo.toml
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
[package]
|
||||||
|
name = "enum_demo"
|
||||||
|
version = "0.1.0"
|
||||||
|
edition = "2021"
|
||||||
|
|
||||||
|
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||||
|
|
||||||
|
[dependencies]
|
7
enum_demo/src/main.rs
Normal file
7
enum_demo/src/main.rs
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
fn main() {
|
||||||
|
let config_max: Option<u8> = Some(3u8);
|
||||||
|
|
||||||
|
if let Option::Some(max) = (config_max) {
|
||||||
|
println! ("极大值被设置为了 {}", max);
|
||||||
|
}
|
||||||
|
}
|
8
error_handling_demo/Cargo.toml
Normal file
8
error_handling_demo/Cargo.toml
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
[package]
|
||||||
|
name = "error_handling_demo"
|
||||||
|
version = "0.1.0"
|
||||||
|
edition = "2021"
|
||||||
|
|
||||||
|
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||||
|
|
||||||
|
[dependencies]
|
9
error_handling_demo/src/main.rs
Normal file
9
error_handling_demo/src/main.rs
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
fn main () {
|
||||||
|
use std::net::IpAddr;
|
||||||
|
|
||||||
|
let home: IpAddr = "192.168.0.255"
|
||||||
|
.parse()
|
||||||
|
.expect("硬编码的 IP 地址应是有效的");
|
||||||
|
|
||||||
|
println! ("{}", home);
|
||||||
|
}
|
8
extern_code/Cargo.toml
Normal file
8
extern_code/Cargo.toml
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
[package]
|
||||||
|
name = "extern_code"
|
||||||
|
version = "0.1.0"
|
||||||
|
edition = "2021"
|
||||||
|
|
||||||
|
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||||
|
|
||||||
|
[dependencies]
|
17
extern_code/src/main.rs
Normal file
17
extern_code/src/main.rs
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
extern "C" {
|
||||||
|
fn abs(input: i32) -> i32;
|
||||||
|
fn sqrt(input: f64) -> f64;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#[no_mangle]
|
||||||
|
pub extern "C" fn call_from_c() {
|
||||||
|
println! ("刚从 C 调用了一个 Rust 函数!");
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
unsafe {
|
||||||
|
println! ("C 语言中 -3 的绝对值为:{},3.0 的平方根为:{}", abs(-3), sqrt(3.0));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
8
fah_to_cels/Cargo.toml
Normal file
8
fah_to_cels/Cargo.toml
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
[package]
|
||||||
|
name = "fah_to_cels"
|
||||||
|
version = "0.1.0"
|
||||||
|
edition = "2021"
|
||||||
|
|
||||||
|
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||||
|
|
||||||
|
[dependencies]
|
67
fah_to_cels/src/main.rs
Normal file
67
fah_to_cels/src/main.rs
Normal file
@ -0,0 +1,67 @@
|
|||||||
|
use std::io;
|
||||||
|
use std::process;
|
||||||
|
|
||||||
|
fn fah_to_cels(f: f32) -> f32 {
|
||||||
|
return (f - 32.0) / 1.8;
|
||||||
|
}
|
||||||
|
|
||||||
|
fn cels_to_fah(c: f32) -> f32 {
|
||||||
|
return c * 1.8 + 32.0;
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
println! ("法式温度与摄氏温度之间的转换");
|
||||||
|
|
||||||
|
loop {
|
||||||
|
println! ("\n-----------------\n请选择:
|
||||||
|
'1'-摄氏温度/'2'-法式温度/'Q'/\"quit\" 退出程序。
|
||||||
|
'1'/'2'/'Q'/\"quit\"[1]:");
|
||||||
|
|
||||||
|
let mut temp_type = String::new();
|
||||||
|
|
||||||
|
io::stdin()
|
||||||
|
.read_line(&mut temp_type)
|
||||||
|
.expect("读取输入失败!");
|
||||||
|
|
||||||
|
let temp_type = temp_type.trim();
|
||||||
|
|
||||||
|
if temp_type.eq("Q") || temp_type.eq("quit") { process::exit(0); }
|
||||||
|
|
||||||
|
if ! temp_type.eq("1") && ! temp_type.eq("2") && ! temp_type.eq("") {
|
||||||
|
println! ("无效输入,请输入 '1'、'2'、'Q'、\"quit\",或直接按下回车键");
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if temp_type.eq("1") || temp_type.eq("") {
|
||||||
|
println! ("请输入要转换的摄氏温度:");
|
||||||
|
let temp = get_temp_input();
|
||||||
|
|
||||||
|
println! ("摄氏温度: {:.2}°C,约为法氏温度:{:.2}°F", temp, cels_to_fah(temp));
|
||||||
|
}
|
||||||
|
|
||||||
|
if temp_type.eq("2") {
|
||||||
|
println! ("请输入要转换的法氏温度:");
|
||||||
|
let temp = get_temp_input();
|
||||||
|
|
||||||
|
println! ("法氏温度:{:.2}°F,约为摄氏温度:{:.2}°C", temp, fah_to_cels(temp));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn get_temp_input() -> f32 {
|
||||||
|
return loop {
|
||||||
|
let mut tmp = String::new();
|
||||||
|
|
||||||
|
io::stdin()
|
||||||
|
.read_line(&mut tmp)
|
||||||
|
.expect("读取输入失败");
|
||||||
|
|
||||||
|
match tmp.trim().parse() {
|
||||||
|
Ok(num) => { break num },
|
||||||
|
Err(_) => {
|
||||||
|
println! ("请输入一个浮点数,比如 -10.0, 15.6");
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
8
fn_pattn_demo/Cargo.toml
Normal file
8
fn_pattn_demo/Cargo.toml
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
[package]
|
||||||
|
name = "fn_pattn_demo"
|
||||||
|
version = "0.1.0"
|
||||||
|
edition = "2021"
|
||||||
|
|
||||||
|
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||||
|
|
||||||
|
[dependencies]
|
8
fn_pattn_demo/src/main.rs
Normal file
8
fn_pattn_demo/src/main.rs
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
fn print_coordinates(&(x, y): &(i32, i32)) {
|
||||||
|
println!("当前坐标:({}, {})", x, y);
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
let point = (3, -5);
|
||||||
|
print_coordinates(&point);
|
||||||
|
}
|
8
for_demo/Cargo.toml
Normal file
8
for_demo/Cargo.toml
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
[package]
|
||||||
|
name = "for_demo"
|
||||||
|
version = "0.1.0"
|
||||||
|
edition = "2021"
|
||||||
|
|
||||||
|
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||||
|
|
||||||
|
[dependencies]
|
7
for_demo/src/main.rs
Normal file
7
for_demo/src/main.rs
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
fn main() {
|
||||||
|
let v = vec! ['a', 'b', 'c'];
|
||||||
|
|
||||||
|
for (index, value) in v.iter().enumerate() {
|
||||||
|
println! ("{} 处于索引 {} 处", value, index);
|
||||||
|
}
|
||||||
|
}
|
8
func_pointer/Cargo.toml
Normal file
8
func_pointer/Cargo.toml
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
[package]
|
||||||
|
name = "func_pointer"
|
||||||
|
version = "0.1.0"
|
||||||
|
edition = "2021"
|
||||||
|
|
||||||
|
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||||
|
|
||||||
|
[dependencies]
|
30
func_pointer/src/main.rs
Normal file
30
func_pointer/src/main.rs
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
fn add_one(x: i32) -> i32 {
|
||||||
|
x + 1
|
||||||
|
}
|
||||||
|
|
||||||
|
fn do_twice(f: fn(i32) -> i32, arg: i32) -> i32 {
|
||||||
|
f(arg) + f(arg)
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
let answer = do_twice(add_one, 5);
|
||||||
|
|
||||||
|
println! ("答案为:{}", answer);
|
||||||
|
|
||||||
|
let list_of_numbers = vec! [1, 2, 3];
|
||||||
|
let list_of_strings: Vec<String> =
|
||||||
|
list_of_numbers.iter().map(ToString::to_string).collect();
|
||||||
|
|
||||||
|
println! ("结果为:{:?}", list_of_strings);
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
|
enum Status {
|
||||||
|
Value(u32),
|
||||||
|
Stop,
|
||||||
|
}
|
||||||
|
|
||||||
|
let mut list_of_statuses: Vec<Status> = (0u32..20).map(Status::Value).collect();
|
||||||
|
list_of_statuses.append(&mut vec! [Status::Stop]);
|
||||||
|
println! ("list_of_statuses: {:?}", list_of_statuses);
|
||||||
|
}
|
8
functions/Cargo.toml
Normal file
8
functions/Cargo.toml
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
[package]
|
||||||
|
name = "functions"
|
||||||
|
version = "0.1.0"
|
||||||
|
edition = "2021"
|
||||||
|
|
||||||
|
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||||
|
|
||||||
|
[dependencies]
|
9
functions/src/main.rs
Normal file
9
functions/src/main.rs
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
fn main() {
|
||||||
|
let x = plus_one(-1);
|
||||||
|
|
||||||
|
println! ("x 的值为:{}", x);
|
||||||
|
}
|
||||||
|
|
||||||
|
fn plus_one(x: i32) -> i32 {
|
||||||
|
x + 1
|
||||||
|
}
|
8
generics_demo/Cargo.toml
Normal file
8
generics_demo/Cargo.toml
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
[package]
|
||||||
|
name = "generics_demo"
|
||||||
|
version = "0.1.0"
|
||||||
|
edition = "2021"
|
||||||
|
|
||||||
|
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||||
|
|
||||||
|
[dependencies]
|
14
generics_demo/src/main.rs
Normal file
14
generics_demo/src/main.rs
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
enum Option_i32 {
|
||||||
|
Some(i32),
|
||||||
|
None,
|
||||||
|
}
|
||||||
|
|
||||||
|
enum Option_f64 {
|
||||||
|
Some(f64),
|
||||||
|
None,
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
let integer = Option_i32::Some(5);
|
||||||
|
let float = Option_f64::Some(5.0);
|
||||||
|
}
|
11
guessing_game/Cargo.toml
Normal file
11
guessing_game/Cargo.toml
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
[package]
|
||||||
|
name = "guessing_game-xfossdotcom"
|
||||||
|
license = "MIT"
|
||||||
|
version = "0.1.1"
|
||||||
|
description = "一个在其中猜出计算机所选数字的有趣游戏。"
|
||||||
|
edition = "2021"
|
||||||
|
|
||||||
|
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||||
|
|
||||||
|
[dependencies]
|
||||||
|
rand = "0.8.3"
|
3
guessing_game/README.md
Normal file
3
guessing_game/README.md
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
# Readme
|
||||||
|
|
||||||
|
这是一个作为把代码箱上传到 [crates.io](https://crates.io) 示例的 Rust 项目。
|
64
guessing_game/src/main.rs
Normal file
64
guessing_game/src/main.rs
Normal file
@ -0,0 +1,64 @@
|
|||||||
|
use rand::Rng;
|
||||||
|
use std::{cmp::Ordering, io, process};
|
||||||
|
|
||||||
|
pub struct Guess {
|
||||||
|
value: i32,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Guess {
|
||||||
|
pub fn new(value: i32) -> Guess {
|
||||||
|
if value < 1 || value > 100 {
|
||||||
|
panic! ("Guess 类型值必须在 1 与 100 之间,收到的是 {}", value);
|
||||||
|
}
|
||||||
|
|
||||||
|
Guess { value }
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn value(&self) -> i32 {
|
||||||
|
self.value
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
loop {
|
||||||
|
println! ("\n---猜出这个数来!---");
|
||||||
|
|
||||||
|
let secret_number: i32 = rand::thread_rng().gen_range(1..101);
|
||||||
|
|
||||||
|
// println! ("随机生成的秘密数字为:{}", secret_number);
|
||||||
|
|
||||||
|
loop {
|
||||||
|
println! ("请输入你猜的数。( ‘Q/quit’ 退出游戏)");
|
||||||
|
|
||||||
|
let mut guess: String = String::new();
|
||||||
|
|
||||||
|
io::stdin()
|
||||||
|
.read_line(&mut guess)
|
||||||
|
.expect("读取行失败......");
|
||||||
|
|
||||||
|
if guess.trim().eq("Q") || guess.trim().eq("quit") { process::exit(0); }
|
||||||
|
|
||||||
|
// let guess: u32 = guess.trim().parse().expect("请输入一个数字!");
|
||||||
|
let guess: i32 = match guess.trim().parse() {
|
||||||
|
Ok(num) => num,
|
||||||
|
Err(_) => { println! ("请输入一个数字!"); continue },
|
||||||
|
};
|
||||||
|
|
||||||
|
if guess < 1 || guess > 100 {
|
||||||
|
println! ("秘密数字将在 1 和 100 之间");
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
println! ("你猜的数为:{}", guess);
|
||||||
|
|
||||||
|
match guess.cmp(&secret_number) {
|
||||||
|
Ordering::Less => println! ("太小了!"),
|
||||||
|
Ordering::Greater => println! ("太大了!"),
|
||||||
|
Ordering::Equal => {
|
||||||
|
println! ("你赢了!");
|
||||||
|
break
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
8
hashmap_demo/Cargo.toml
Normal file
8
hashmap_demo/Cargo.toml
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
[package]
|
||||||
|
name = "hashmap_demo"
|
||||||
|
version = "0.1.0"
|
||||||
|
edition = "2021"
|
||||||
|
|
||||||
|
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||||
|
|
||||||
|
[dependencies]
|
14
hashmap_demo/src/main.rs
Normal file
14
hashmap_demo/src/main.rs
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
fn main() {
|
||||||
|
use std::collections::HashMap;
|
||||||
|
|
||||||
|
let text = "hello world wonderful world";
|
||||||
|
|
||||||
|
let mut map = HashMap::new();
|
||||||
|
|
||||||
|
for word in text.split_whitespace() {
|
||||||
|
let count = map.entry(word).or_insert(0);
|
||||||
|
*count += 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
println! ("{:?}", map);
|
||||||
|
}
|
11
hello/404.html
Normal file
11
hello/404.html
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="en">
|
||||||
|
<head>
|
||||||
|
<meta charset="utf-8">
|
||||||
|
<title>你好!</title>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<h1>糟糕!</h1>
|
||||||
|
<p>抱歉,我不明白你要什么。</p>
|
||||||
|
</body>
|
||||||
|
</html>
|
8
hello/Cargo.toml
Normal file
8
hello/Cargo.toml
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
[package]
|
||||||
|
name = "hello"
|
||||||
|
version = "0.1.0"
|
||||||
|
edition = "2021"
|
||||||
|
|
||||||
|
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||||
|
|
||||||
|
[dependencies]
|
11
hello/hello.html
Normal file
11
hello/hello.html
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="en">
|
||||||
|
<head>
|
||||||
|
<meta charset="utf-8">
|
||||||
|
<title>你好!</title>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<h1>你好!</h1>
|
||||||
|
<p>来自 Rust 的问好</p>
|
||||||
|
</body>
|
||||||
|
</html>
|
35
hello/src/main.rs
Normal file
35
hello/src/main.rs
Normal file
@ -0,0 +1,35 @@
|
|||||||
|
#![allow(warnings)]
|
||||||
|
use std::{
|
||||||
|
fs,
|
||||||
|
io::{prelude::*, BufReader},
|
||||||
|
net::{TcpListener, TcpStream},
|
||||||
|
};
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
let listener = TcpListener::bind("127.0.0.1:7878").unwrap();
|
||||||
|
|
||||||
|
for stream in listener.incoming() {
|
||||||
|
let stream = stream.unwrap();
|
||||||
|
|
||||||
|
handle_conn(stream);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn handle_conn(mut stream: TcpStream) {
|
||||||
|
let buf_reader = BufReader::new(&mut stream);
|
||||||
|
let req_line = buf_reader.lines().next().unwrap().unwrap();
|
||||||
|
|
||||||
|
let (status_line, filename) = if req_line == "GET / HTTP/1.1" {
|
||||||
|
( "HTTP/1.1 200 OK", "hello.html")
|
||||||
|
} else {
|
||||||
|
("HTTP/1.1 404 NOT FOUND", "404.html")
|
||||||
|
};
|
||||||
|
|
||||||
|
let contents = fs::read_to_string(filename).unwrap();
|
||||||
|
let length = contents.len();
|
||||||
|
|
||||||
|
let resp =
|
||||||
|
format! ("{status_line}\r\nContent-Length: {length}\r\n\r\n{contents}");
|
||||||
|
|
||||||
|
stream.write_all(resp.as_bytes()).unwrap();
|
||||||
|
}
|
8
hello_cargo/Cargo.toml
Normal file
8
hello_cargo/Cargo.toml
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
[package]
|
||||||
|
name = "hello_cargo"
|
||||||
|
version = "0.1.0"
|
||||||
|
edition = "2021"
|
||||||
|
|
||||||
|
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||||
|
|
||||||
|
[dependencies]
|
4
hello_cargo/src/main.rs
Normal file
4
hello_cargo/src/main.rs
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
fn main() {
|
||||||
|
// 这是注释。
|
||||||
|
println! ("Hello, Cargo!");
|
||||||
|
}
|
8
hello_macro/Cargo.toml
Normal file
8
hello_macro/Cargo.toml
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
[package]
|
||||||
|
name = "hello_macro"
|
||||||
|
version = "0.1.0"
|
||||||
|
edition = "2021"
|
||||||
|
|
||||||
|
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||||
|
|
||||||
|
[dependencies]
|
12
hello_macro/hello_macro_derive/Cargo.toml
Normal file
12
hello_macro/hello_macro_derive/Cargo.toml
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
[package]
|
||||||
|
name = "hello_macro_derive"
|
||||||
|
version = "0.1.0"
|
||||||
|
edition = "2021"
|
||||||
|
|
||||||
|
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||||
|
[lib]
|
||||||
|
proc-macro = true
|
||||||
|
|
||||||
|
[dependencies]
|
||||||
|
syn = "1.0"
|
||||||
|
quote = "1.0"
|
26
hello_macro/hello_macro_derive/src/lib.rs
Normal file
26
hello_macro/hello_macro_derive/src/lib.rs
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
use proc_macro::TokenStream;
|
||||||
|
use quote::quote;
|
||||||
|
use syn;
|
||||||
|
|
||||||
|
#[proc_macro_derive(HelloMacro)]
|
||||||
|
pub fn hello_macro_derive(input: TokenStream) -> TokenStream {
|
||||||
|
// 以语法树形式,构建出咱们可操作 Rust 代码的表示
|
||||||
|
// Construct a representation of Rust code as a syntax tree
|
||||||
|
// that we can manipulate
|
||||||
|
let ast = syn::parse(input).unwrap();
|
||||||
|
|
||||||
|
// 构造出这个特质实现
|
||||||
|
impl_hello_macro(&ast)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn impl_hello_macro(ast: &syn::DeriveInput) -> TokenStream {
|
||||||
|
let name = &ast.ident;
|
||||||
|
let gen = quote! {
|
||||||
|
impl HelloMacro for #name {
|
||||||
|
fn hello_macro() {
|
||||||
|
println! ("你好,宏!我的名字叫 {}!", stringify! (#name));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
gen.into()
|
||||||
|
}
|
3
hello_macro/src/lib.rs
Normal file
3
hello_macro/src/lib.rs
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
pub trait HelloMacro {
|
||||||
|
fn hello_macro();
|
||||||
|
}
|
8
hello_macro_derive/Cargo.toml
Normal file
8
hello_macro_derive/Cargo.toml
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
[package]
|
||||||
|
name = "hello_macro_derive"
|
||||||
|
version = "0.1.0"
|
||||||
|
edition = "2021"
|
||||||
|
|
||||||
|
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||||
|
|
||||||
|
[dependencies]
|
14
hello_macro_derive/src/lib.rs
Normal file
14
hello_macro_derive/src/lib.rs
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
pub fn add(left: usize, right: usize) -> usize {
|
||||||
|
left + right
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod tests {
|
||||||
|
use super::*;
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn it_works() {
|
||||||
|
let result = add(2, 2);
|
||||||
|
assert_eq!(result, 4);
|
||||||
|
}
|
||||||
|
}
|
8
hello_world/Cargo.toml
Normal file
8
hello_world/Cargo.toml
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
[package]
|
||||||
|
name = "hello_world"
|
||||||
|
version = "0.1.0"
|
||||||
|
edition = "2021"
|
||||||
|
|
||||||
|
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||||
|
|
||||||
|
[dependencies]
|
4
hello_world/src/main.rs
Normal file
4
hello_world/src/main.rs
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
fn main() {
|
||||||
|
// 这是注释。
|
||||||
|
println!("Hello, World!");
|
||||||
|
}
|
8
if_let_demo/Cargo.toml
Normal file
8
if_let_demo/Cargo.toml
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
[package]
|
||||||
|
name = "if_let_demo"
|
||||||
|
version = "0.1.0"
|
||||||
|
edition = "2021"
|
||||||
|
|
||||||
|
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||||
|
|
||||||
|
[dependencies]
|
22
if_let_demo/src/main.rs
Normal file
22
if_let_demo/src/main.rs
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
#![allow(dead_code)]
|
||||||
|
#![allow(unused_variables)]
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
let favorite_color: Option<&str> = None;
|
||||||
|
let is_tuesday = false;
|
||||||
|
let age: Result<u8, _> = "34".parse();
|
||||||
|
|
||||||
|
if let Some(color) = favorite_color {
|
||||||
|
println! ("使用你喜欢的颜色,{color},作为背景");
|
||||||
|
} else if is_tuesday {
|
||||||
|
println! ("周二是绿色的一天!");
|
||||||
|
} else if let Ok(age) = age {
|
||||||
|
if age > 30 {
|
||||||
|
println! ("使用紫色作为背景色");
|
||||||
|
} else {
|
||||||
|
println! ("使用橙色作为背景色");
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
println! ("使用蓝色作为背景色");
|
||||||
|
}
|
||||||
|
}
|
8
iterator_demo/Cargo.toml
Normal file
8
iterator_demo/Cargo.toml
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
[package]
|
||||||
|
name = "iterator_demo"
|
||||||
|
version = "0.1.0"
|
||||||
|
edition = "2021"
|
||||||
|
|
||||||
|
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||||
|
|
||||||
|
[dependencies]
|
35
iterator_demo/src/lib.rs
Normal file
35
iterator_demo/src/lib.rs
Normal file
@ -0,0 +1,35 @@
|
|||||||
|
#[derive(PartialEq, Debug)]
|
||||||
|
struct Shoe {
|
||||||
|
size: u32,
|
||||||
|
style: String,
|
||||||
|
}
|
||||||
|
|
||||||
|
fn shoes_in_size(shoes: Vec<Shoe>, shoe_size: u32) -> Vec<Shoe> {
|
||||||
|
shoes.into_iter().filter(|s| s.size == shoe_size).collect()
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod tests;
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn iterator_demonstration() {
|
||||||
|
let v1 = vec! [1, 2, 3];
|
||||||
|
|
||||||
|
let mut v1_iter = v1.iter();
|
||||||
|
|
||||||
|
assert_eq! (v1_iter.next(), Some(&1));
|
||||||
|
assert_eq! (v1_iter.next(), Some(&2));
|
||||||
|
assert_eq! (v1_iter.next(), Some(&3));
|
||||||
|
assert_eq! (v1_iter.next(), None);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn iterator_sum() {
|
||||||
|
let v1 = vec! [1, 2, 3];
|
||||||
|
|
||||||
|
let v1_iter = v1.iter();
|
||||||
|
|
||||||
|
let total: i32 = v1_iter.sum();
|
||||||
|
|
||||||
|
assert_eq! (total, 6);
|
||||||
|
}
|
7
iterator_demo/src/main.rs
Normal file
7
iterator_demo/src/main.rs
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
fn main() {
|
||||||
|
let v1 = vec! [1, 2, 3];
|
||||||
|
|
||||||
|
let v2: Vec<_> = v1.iter().map(|x| x + 1).collect();
|
||||||
|
|
||||||
|
assert_eq! (v2, vec! [2, 3, 4]);
|
||||||
|
}
|
35
iterator_demo/src/tests.rs
Normal file
35
iterator_demo/src/tests.rs
Normal file
@ -0,0 +1,35 @@
|
|||||||
|
use super::*;
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn filter_by_size() {
|
||||||
|
let shoes = vec! [
|
||||||
|
Shoe {
|
||||||
|
size: 10,
|
||||||
|
style: String::from("sneaker"),
|
||||||
|
},
|
||||||
|
Shoe {
|
||||||
|
size: 13,
|
||||||
|
style: String::from("sandal"),
|
||||||
|
},
|
||||||
|
Shoe {
|
||||||
|
size: 10,
|
||||||
|
style: String::from("boot"),
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
|
let in_my_size = shoes_in_size(shoes, 10);
|
||||||
|
|
||||||
|
assert_eq! (
|
||||||
|
in_my_size,
|
||||||
|
vec! [
|
||||||
|
Shoe {
|
||||||
|
size: 10,
|
||||||
|
style: String::from("sneaker"),
|
||||||
|
},
|
||||||
|
Shoe {
|
||||||
|
size: 10,
|
||||||
|
style: String::from("boot"),
|
||||||
|
},
|
||||||
|
]
|
||||||
|
);
|
||||||
|
}
|
8
lifetimes_demo/Cargo.toml
Normal file
8
lifetimes_demo/Cargo.toml
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
[package]
|
||||||
|
name = "lifetimes_demo"
|
||||||
|
version = "0.1.0"
|
||||||
|
edition = "2021"
|
||||||
|
|
||||||
|
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||||
|
|
||||||
|
[dependencies]
|
23
lifetimes_demo/src/main.rs
Normal file
23
lifetimes_demo/src/main.rs
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
use std::fmt::Display;
|
||||||
|
|
||||||
|
fn longest_with_an_announcement<'a, T>(
|
||||||
|
x: &'a str,
|
||||||
|
y: &'a str,
|
||||||
|
ann: T,
|
||||||
|
) -> &'a str
|
||||||
|
where
|
||||||
|
T: Display,
|
||||||
|
{
|
||||||
|
println! ("通知!{}", ann);
|
||||||
|
if x.len() > y.len() {
|
||||||
|
x
|
||||||
|
} else {
|
||||||
|
y
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
let result = longest_with_an_announcement("abc", "测试", "计算结果已出来。");
|
||||||
|
|
||||||
|
println! ("{}", result);
|
||||||
|
}
|
8
limit_tracker/Cargo.toml
Normal file
8
limit_tracker/Cargo.toml
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
[package]
|
||||||
|
name = "limit_tracker"
|
||||||
|
version = "0.1.0"
|
||||||
|
edition = "2021"
|
||||||
|
|
||||||
|
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||||
|
|
||||||
|
[dependencies]
|
77
limit_tracker/src/lib.rs
Normal file
77
limit_tracker/src/lib.rs
Normal file
@ -0,0 +1,77 @@
|
|||||||
|
pub trait Messenger {
|
||||||
|
fn send(&self, msg: &str);
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct LimitTracker<'a, T: Messenger> {
|
||||||
|
messenger: &'a T,
|
||||||
|
value: usize,
|
||||||
|
max: usize,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a, T> LimitTracker<'a, T>
|
||||||
|
where
|
||||||
|
T: Messenger,
|
||||||
|
{
|
||||||
|
pub fn new(messenger: &'a T, max: usize) -> LimitTracker<'a, T> {
|
||||||
|
LimitTracker {
|
||||||
|
messenger,
|
||||||
|
value: 0,
|
||||||
|
max,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn set_value(&mut self, value: usize) {
|
||||||
|
self.value = value;
|
||||||
|
|
||||||
|
let percentage_of_max = self.value as f64 / self.max as f64;
|
||||||
|
|
||||||
|
if percentage_of_max >= 1.0 {
|
||||||
|
self.messenger.send("出错:你已超出你的配额!");
|
||||||
|
} else if percentage_of_max >= 0.9 {
|
||||||
|
self.messenger
|
||||||
|
.send("紧急警告:你已用掉你配额的 90% !");
|
||||||
|
} else if percentage_of_max >= 0.75 {
|
||||||
|
self.messenger
|
||||||
|
.send("警告:你已用掉你配额的 75% !");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod tests {
|
||||||
|
use super::*;
|
||||||
|
use std::cell::RefCell;
|
||||||
|
|
||||||
|
struct MockMessenger {
|
||||||
|
sent_messages: RefCell<Vec<String>>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl MockMessenger {
|
||||||
|
fn new() -> MockMessenger {
|
||||||
|
MockMessenger {
|
||||||
|
sent_messages: RefCell::new(vec! []),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Messenger for MockMessenger {
|
||||||
|
fn send(&self, message: &str) {
|
||||||
|
let mut borrow_one = self.sent_messages.borrow_mut();
|
||||||
|
let mut borrow_two = self.sent_messages.borrow_mut();
|
||||||
|
|
||||||
|
borrow_one.push(String::from(message));
|
||||||
|
borrow_two.push(String::from(message));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn it_sends_an_over_75_percent_waring_message() {
|
||||||
|
let mock_messenger = MockMessenger::new();
|
||||||
|
let mut limit_tracker = LimitTracker::new(&mock_messenger, 100);
|
||||||
|
|
||||||
|
limit_tracker.set_value(80);
|
||||||
|
println! ("{}", mock_messenger.sent_messages.borrow().iter().next().unwrap());
|
||||||
|
|
||||||
|
assert_eq! (mock_messenger.sent_messages.borrow().len(), 1);
|
||||||
|
}
|
||||||
|
}
|
8
loops/Cargo.toml
Normal file
8
loops/Cargo.toml
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
[package]
|
||||||
|
name = "loops"
|
||||||
|
version = "0.1.0"
|
||||||
|
edition = "2021"
|
||||||
|
|
||||||
|
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||||
|
|
||||||
|
[dependencies]
|
7
loops/src/main.rs
Normal file
7
loops/src/main.rs
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
fn main() {
|
||||||
|
for number in (1..4).rev() {
|
||||||
|
println! ("{}!", number);
|
||||||
|
}
|
||||||
|
|
||||||
|
println! ("发射!!");
|
||||||
|
}
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user