Skip to content

Commit 4fed868

Browse files
committed
chore & feat commit rust learn by books
0 parents  commit 4fed868

File tree

366 files changed

+14255
-0
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

366 files changed

+14255
-0
lines changed

.gitignore

+3
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
2+
target
3+
dist

README.md

+59
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
# Rust Learn
2+
3+
- Rust官网【Rust程序设计语言】随书笔记与代码
4+
5+
- [参考地址](https://kaisery.github.io/trpl-zh-cn/ch19-03-advanced-traits.html)
6+
7+
## 简略
8+
9+
- 命令行工具
10+
- 网络服务器
11+
- 网页应用
12+
- 嵌入式开发
13+
-
14+
15+
- rust编译器很重要
16+
17+
- cargo
18+
- rustfmt
19+
- rust language server
20+
21+
- 操作系统开发、命令行工具、网络服务、DevOps工具、嵌入式设备、音视频分析与转码、加密货币、生物信息学、搜索引擎、IOT、ML等
22+
23+
- 零开销抽象
24+
- 将高级语言特性编译为底层代码,并且与手写的代码运行速度同样快
25+
26+
- 安全、高效、速度、易读易用兼得
27+
28+
- 概念章节
29+
- 项目章节
30+
31+
- 所有权ownership
32+
33+
- struct, enum, match, if let, module, vector, string, hash map
34+
- 私有性与公开api
35+
- 错误处理技术和理念
36+
- 泛型generic、Trait、lifetime
37+
- grep
38+
- closure闭包,iterator, 函数式编程
39+
- 并发编程模型,thread
40+
- 模式和模式匹配
41+
- unsafe rust
42+
- macro 类型,函数与闭包
43+
44+
- 预编译静态类型ahead-of-time compiled
45+
46+
- cargo是rust的构建系统和包管理器
47+
48+
- 依赖dependencies
49+
50+
- cargo new project_name
51+
- cargo build,构建项目
52+
- cargo run ,构建并运行项目
53+
- cargo check,在不生成二级文件的情况下构建项目来检查错误
54+
- cargo release
55+
- cargo update
56+
57+
## Rust WebService
58+
59+
## Rust Yew
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
# 高级函数和闭包
2+
3+
- 函数指针以及返回值闭包
4+
5+
- 函数指针
6+
- 通过函数指针允许我们使用函数作为另一个函数的参数
7+
- 函数的类型是fn,以免和Fn闭包trait相混淆
8+
- fn被称为函数指针
9+
- 指定参数为函数指针的语法类似于闭包
10+
11+
```rs
12+
fn add_one(x: i32) -> i32 {
13+
x + 1
14+
}
15+
16+
fn do_twice(f: fn(i32) -> i32, arg: i32) -> i32 {
17+
f(arg) + f(arg)
18+
}
19+
20+
fn main() {
21+
let answer = do_twice(add_one, 5);
22+
23+
println!("The answer is : {}", answer);
24+
}
25+
```
26+
27+
- 不同于闭包,fn是一个类型而不是trait,所以直接指定fn作为参数而不是2声明一个带有Fn作为trait bound的泛型参数
28+
29+
- 函数指针实现了所有三个闭包trait(Fn、FnMut、FnOnce),所以总是可以在调用期望闭包的函数时传递函数指针作为参数
30+
31+
- 倾向于编写使用泛型和闭包 trait 的函数,这样它就能接受函数或闭包作为参数
32+
33+
- 一个只期望接受 fn 而不接受闭包的情况的例子是与不存在闭包的外部代码交互时:C 语言的函数可以接受函数作为参数,但 C 语言没有闭包
34+
35+
- 完全限定语法
36+
37+
- 另一个实用的模式暴露了元组结构体和元组结构体枚举成员的实现细节
38+
39+
```rs
40+
enum Status {
41+
Value(u32),
42+
Stop,
43+
}
44+
45+
let list_of_statuses: Vec<Status> = (0u32..20).map(Status::Value).collect();
46+
```
47+
48+
- 返回闭包
49+
- 闭包表现为trait,这意味着不能直接返回闭包
50+
- 对于大部分需要返回trait的情况,可以使用实现了期望返回的trait的具体类型来替代函数的返回值会
51+
52+
```rs
53+
// error
54+
55+
fn returns_closure() -> Box<dyn Fn(i32) -> i32> {
56+
Box::new(|x| x+1)
57+
}
58+
```
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
# 高级trait
2+
3+
## 关联类型在trait定义中指定占位符类型
4+
5+
- 关联类型是一个将类型占位符与trait相关联的方式
6+
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,149 @@
1+
# 高级类型
2+
3+
- newtype与类型一样有用
4+
5+
- 类型别名
6+
7+
- `!`类型
8+
9+
- 动态大小类型
10+
11+
## 为了类型安全和抽象而使用newtype模式
12+
13+
- 静态的确保某值不被混淆,和用来表示一个值的单元
14+
15+
- 抽象掉一些类型的实现细节,例如封装类型可以暴露出与直接使用其内部私有类型时所不同的公有API,以便于限制其功能
16+
17+
- newtype还可以隐藏内部的泛型类型
18+
19+
- newtype模式是一种隐藏实现细节的封装的轻量级方法
20+
21+
## 类型别名用来创建类型同义词
22+
23+
- 类型别名,使用type关键字来给予现有类型另一个名字
24+
```rs
25+
type Kilometers = i32;
26+
27+
let x: i32 = 5;
28+
let y: Kilometers = 5;
29+
30+
println!("x + y = {}", x + y);
31+
```
32+
33+
- 类型别名的主要用途是减少重复
34+
35+
```rs
36+
Box<dyn Fn() + Send + 'static>
37+
38+
type Thunk = Box<dyn Fn() + Send + 'static>
39+
40+
let f: Thunk = Box::new(|| println!("hi"));
41+
42+
fn takes_long_type(f: Thunk) {
43+
44+
}
45+
46+
fn returns_loong_type() -> Thunk {
47+
48+
}
49+
```
50+
51+
- 类型别名也经常与`Result<T, E>`结合用来减少重复
52+
53+
```rs
54+
use std::fmt;
55+
use std::io::Error;
56+
57+
type Result<T> = std::result::Result<T, std::io::Error>;
58+
59+
pub trait Write {
60+
fn write(&mut self, buf: &[u8]) -> Result<usize>;
61+
fn flush(&mut self) -> Result<()>;
62+
63+
fn write_all(&mut self, buf: &[u8]) -> Result<()>;
64+
fn write_fmt(&mut self, fmt: fmt::Arguments) -> Result<()>;
65+
}
66+
```
67+
68+
## 从不返回的never type
69+
70+
- `!`类型,empty type,没有值,或者称之为never type
71+
- 作用:在函数从不返回的时候充当返回值
72+
73+
```rs
74+
fn bar() -> ! {
75+
76+
}
77+
```
78+
79+
- 从不返回的函数被称为发散函数
80+
81+
- 描述!的行为的正式方式是never type可以强转为任何其他类型
82+
83+
- 允许match的分支以continue结束是因为continue并不真正返回一个值;相反它把控制权交回上层循环,所以在Err的情况,事实上并未对guess赋值
84+
85+
- never type的另一个用途就是panic!
86+
87+
- panic! 是 ! 类型,所以整个 match 表达式的结果是 T 类型
88+
89+
- loop也有!类型
90+
91+
```rs
92+
impl<T> Option<T> {
93+
pub fn unwrap(self) -> T {
94+
match self {
95+
Some(val) => val,
96+
None => panic!("called `Option::unwrap()` on a `None` value"),
97+
}
98+
}
99+
}
100+
101+
print!("forever")
102+
loop {
103+
print!(and ever)
104+
}
105+
```
106+
107+
## 动态大小类型和Sized trait
108+
109+
- DST或unsized types
110+
111+
- str是一个DST
112+
113+
```rs
114+
// error
115+
let s1: str = "Hello there!";
116+
let s2: str = "How's it going?"
117+
```
118+
119+
- &str有两个值:str的地址和其长度
120+
121+
- 动态大小类型的黄金法则:必须将动态大小类型的值置于某种指针之后
122+
123+
- sized trait
124+
125+
- rust隐式的为每一个泛型函数增加了Sized bound
126+
127+
```rs
128+
fn generic<T>(t: T) {
129+
130+
}
131+
132+
// 实际上
133+
fn generic<T: Sized>(t: T) {
134+
135+
}
136+
```
137+
138+
- 泛型函数默认只能用于编译时已知大小的类型
139+
140+
```rs
141+
fn generic<T: ?sized>(t: &T) {
142+
143+
}
144+
```
145+
146+
- ?Sized上的trait bound意味着T可能是也可能不是sized 同时这个注解会覆盖泛型类型必须在编译时拥有固定大小的默认规则。
147+
- 这种意义的 ?Trait 语法只能用于 Sized ,而不能用于任何其他 trait。
148+
149+
- 另外注意我们将 t 参数的类型从 T 变为了 &T:因为其类型可能不是 Sized 的,所以需要将其置于某种指针之后。在这个例子中选择了引用。
+47
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
#
2+
3+
- 什么是宏?
4+
- 宏怎么工作?
5+
6+
- 宏Macro指的是Rust中一系列的功能:使用macro_rules!的声明宏,和三种过程宏
7+
- 自定义`#[derive]`宏在结构体和枚举上指定通过dervie属性添加的代码
8+
- 类属性宏定义可用于任意项的2自定义属性
9+
- 类函数宏看起来像函数不过作用于参数传递的token
10+
11+
## 宏和函数的区别
12+
- 从根本上来说,宏是一种为写其他代码而写代码的方式,即所谓的元编程
13+
14+
- 元编程对于减少大量编程和维护的代码是非常有用的,它也扮演了函数扮演的角色。但宏有函数所没有的附加功能
15+
16+
- 实现宏不如实现函数的一面是宏定义要比函数定义更复杂,因为你正在编写生成 Rust 代码的 Rust 代码。由于这样的间接性,宏定义通常要比函数定义更难阅读、理解以及维护
17+
18+
- 宏和函数的最后一个重要区别是:在一个文件里调用宏之前必须定义它或将其引入作用域,而函数则可以在任何地方定义和调用
19+
20+
## 使用macro_rules!的声明宏用于通用元编程
21+
22+
- 声明宏允许我们编写一些类似Rust match 表达式的代码
23+
24+
- `#[macro_export]`,注解表明只要导入了定义这个宏的crate,该宏就应该是可用的。
25+
26+
- `macro_rules!`,用来定义宏
27+
28+
- 分支模式`( $( $x:expr ),* )`
29+
30+
- 宏模式匹配的是Rust代码结构而不是值
31+
32+
- macro 关键字
33+
34+
## 用于从属性生成代码的过程宏
35+
- 更像函数,接收Rust代码作为输入,产生另一些代码作为输出
36+
37+
- 三种过程宏:
38+
- 自定义派生derive
39+
- 类属性
40+
- 类函数
41+
42+
## 如何编写自定义derive宏
43+
44+
45+
## 类属性宏
46+
47+
## 类函数宏

0 commit comments

Comments
 (0)