Skip to content

Commit

Permalink
unsafe 使用
Browse files Browse the repository at this point in the history
  • Loading branch information
Danny5487401 committed Aug 30, 2024
1 parent 7505665 commit 70ccf33
Show file tree
Hide file tree
Showing 19 changed files with 258 additions and 24 deletions.
1 change: 1 addition & 0 deletions .idea/advanced_rust.iml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 4 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
members = ["app", "chapter01-log",
"chapter02-feature", "chapter03-ownership",
"chapter04-lifecycle", "chapter05-memory", "chapter06-type",
"chapter07-pointer", "chapter08-vec", "chapter09-hash", "chapter10-error", "chapter11-closure"]
"chapter07-pointer", "chapter08-vec", "chapter09-hash", "chapter10-error", "chapter11-closure", "chapter12-unsafe"]


[workspace.dependencies]
Expand Down
30 changes: 19 additions & 11 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,18 @@
**Table of Contents** *generated with [DocToc](https://github.com/thlorenz/doctoc)*

- [**rust 背包客**](#rust-%E8%83%8C%E5%8C%85%E5%AE%A2)
- [第二章:feature 条件编译](#%E7%AC%AC%E4%BA%8C%E7%AB%A0feature-%E6%9D%A1%E4%BB%B6%E7%BC%96%E8%AF%91)
- [第三章:所有权](#%E7%AC%AC%E4%B8%89%E7%AB%A0%E6%89%80%E6%9C%89%E6%9D%83)
- [第四章:生命周期](#%E7%AC%AC%E5%9B%9B%E7%AB%A0%E7%94%9F%E5%91%BD%E5%91%A8%E6%9C%9F)
- [第五章:内存模型](#%E7%AC%AC%E4%BA%94%E7%AB%A0%E5%86%85%E5%AD%98%E6%A8%A1%E5%9E%8B)
- [第六章:类型](#%E7%AC%AC%E5%85%AD%E7%AB%A0%E7%B1%BB%E5%9E%8B)
- [第七章:指针](#%E7%AC%AC%E4%B8%83%E7%AB%A0%E6%8C%87%E9%92%88)
- [第八章:集合容器](#%E7%AC%AC%E5%85%AB%E7%AB%A0%E9%9B%86%E5%90%88%E5%AE%B9%E5%99%A8)
- [参考](#%E5%8F%82%E8%80%83)
- [第二章:feature 条件编译](#%E7%AC%AC%E4%BA%8C%E7%AB%A0feature-%E6%9D%A1%E4%BB%B6%E7%BC%96%E8%AF%91)
- [第三章:所有权](#%E7%AC%AC%E4%B8%89%E7%AB%A0%E6%89%80%E6%9C%89%E6%9D%83)
- [第四章:生命周期](#%E7%AC%AC%E5%9B%9B%E7%AB%A0%E7%94%9F%E5%91%BD%E5%91%A8%E6%9C%9F)
- [第五章:内存模型](#%E7%AC%AC%E4%BA%94%E7%AB%A0%E5%86%85%E5%AD%98%E6%A8%A1%E5%9E%8B)
- [第六章:类型](#%E7%AC%AC%E5%85%AD%E7%AB%A0%E7%B1%BB%E5%9E%8B)
- [第七章:指针](#%E7%AC%AC%E4%B8%83%E7%AB%A0%E6%8C%87%E9%92%88)
- [第八章:集合容器](#%E7%AC%AC%E5%85%AB%E7%AB%A0%E9%9B%86%E5%90%88%E5%AE%B9%E5%99%A8)
- [第九章:hash](#%E7%AC%AC%E4%B9%9D%E7%AB%A0hash)
- [第十章:error 错误处理](#%E7%AC%AC%E5%8D%81%E7%AB%A0error-%E9%94%99%E8%AF%AF%E5%A4%84%E7%90%86)
- [第十一章:闭包](#%E7%AC%AC%E5%8D%81%E4%B8%80%E7%AB%A0%E9%97%AD%E5%8C%85)
- [第十二章:unsafe](#%E7%AC%AC%E5%8D%81%E4%BA%8C%E7%AB%A0unsafe)
- [参考](#%E5%8F%82%E8%80%83)

<!-- END doctoc generated TOC please keep comment here to allow auto update -->

Expand All @@ -30,7 +34,7 @@
- 3 Borrow 借用(通过 & 或者 &mut)
- 4 多个所有者
- 4.1 非线程安全 Rc(Reference counter 只读引用计数器)
- [4.2 非线程安全 RefCell 实现内部可变性](chapter03-ownership/src/ownership1.rs)
- [4.2 非线程安全 RefCell 实现内部可变性](chapter03-ownership/src/ownership1-borrow-mut)
- 4.3 线程安全 Arc(Atomic reference counter)
- 4.4 线程安全 Mutex 和 RwLock 实现内部可变性
- [5 Clone 数据深拷贝](chapter03-ownership/src/ownership3-clone.rs)
Expand Down Expand Up @@ -71,7 +75,7 @@

## [第九章:hash](chapter09-hash/hashmap.md)

- 1 hashmap cap 扩容和缩容
- [1 hashmap cap 扩容和缩容](chapter09-hash/src/hash1-cap.rs)
- 2 HashSet
- 3 BTreeMap

Expand All @@ -81,7 +85,11 @@

## [第十一章:闭包](chapter11-closure/closure.md)

- 1 闭包的大小跟参数、局部变量都无关,只跟捕获的变量有关
- [1 闭包的大小跟参数、局部变量都无关,只跟捕获的变量有关](chapter11-closure/src/closure1-size.rs)

## [第十二章:unsafe](chapter12-unsafe/unsafe.md)

- [1 开发者还是调用者保证内存安全](chapter12-unsafe/src/unsafe1-caller.rs)

## 参考

Expand Down
2 changes: 1 addition & 1 deletion chapter03-ownership/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ authors.workspace = true

[[bin]]
name = "ownership1"
path = "src/ownership1.rs"
path = "src/ownership1-borrow-mut.rs"


[[bin]]
Expand Down
File renamed without changes.
2 changes: 2 additions & 0 deletions chapter06-type/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -36,5 +36,7 @@ path = "src/type6-asref.rs"
name = "type7"
path = "src/type7-deref.rs"



[dependencies]
regex = { version = "1.10.6" }
23 changes: 16 additions & 7 deletions chapter06-type/type.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,12 @@

- [多态实现](#%E5%A4%9A%E6%80%81%E5%AE%9E%E7%8E%B0)
- [unit()](#unit)
- [用泛型实现 参数多态](#%E7%94%A8%E6%B3%9B%E5%9E%8B%E5%AE%9E%E7%8E%B0-%E5%8F%82%E6%95%B0%E5%A4%9A%E6%80%81)
- [用泛型实现*参数多态*](#%E7%94%A8%E6%B3%9B%E5%9E%8B%E5%AE%9E%E7%8E%B0%E5%8F%82%E6%95%B0%E5%A4%9A%E6%80%81)
- [泛型函数](#%E6%B3%9B%E5%9E%8B%E5%87%BD%E6%95%B0)
- [trait 实现特设多态](#trait-%E5%AE%9E%E7%8E%B0%E7%89%B9%E8%AE%BE%E5%A4%9A%E6%80%81)
- [泛型参数](#%E6%B3%9B%E5%9E%8B%E5%8F%82%E6%95%B0)
- [trait 实现*特设多态*](#trait-%E5%AE%9E%E7%8E%B0%E7%89%B9%E8%AE%BE%E5%A4%9A%E6%80%81)
- [带关联类型的 trait](#%E5%B8%A6%E5%85%B3%E8%81%94%E7%B1%BB%E5%9E%8B%E7%9A%84-trait)
- [子类型多态](#%E5%AD%90%E7%B1%BB%E5%9E%8B%E5%A4%9A%E6%80%81)
- [泛型函数实现*子类型多态*](#%E6%B3%9B%E5%9E%8B%E5%87%BD%E6%95%B0%E5%AE%9E%E7%8E%B0%E5%AD%90%E7%B1%BB%E5%9E%8B%E5%A4%9A%E6%80%81)
- [Trait Object](#trait-object)
- [类型转换](#%E7%B1%BB%E5%9E%8B%E8%BD%AC%E6%8D%A2)

Expand Down Expand Up @@ -42,7 +43,7 @@ fn work(has_work: bool) {
}
```

## 用泛型实现 参数多态
## 用泛型实现*参数多态*

函数,是把重复代码中的参数抽取出来,使其更加通用,调用函数的时候,根据参数的不同,我们得到不同的结果;

Expand Down Expand Up @@ -77,9 +78,17 @@ B 的三个约束分别是:

### 泛型函数

对于泛型函数,Rust 会进行单态化(Monomorphization)处理,也就是在编译时,把所有用到的泛型函数的泛型参数展开,生成若干个函数
对于泛型函数,Rust 会进行单态化(Monomorphization)处理,也就是在编译时,把所有用到的泛型函数的泛型参数展开,生成若干个函数

## trait 实现特设多态
### 泛型参数

它有三种常见的使用场景:

- 使用泛型参数延迟数据结构的绑定;
- 使用泛型参数和 PhantomData,声明数据结构中不直接使用,但在实现过程中需要用到的类型;
- 使用泛型参数让同一个数据结构对同一个 trait 可以拥有不同的实现。

## trait 实现*特设多态*

![img.png](trait_all.png)

Expand Down Expand Up @@ -216,7 +225,7 @@ pub trait Parse {

trait 方法里的参数或者返回值,都可以用关联类型来表述,而在实现有关联类型的 trait 时,只需要额外提供关联类型的具体类型即可

## 子类型多态
## 泛型函数实现*子类型多态*

```rust
// 泛型函数
Expand Down
12 changes: 12 additions & 0 deletions chapter09-hash/hashmap.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,15 @@
<!-- START doctoc generated TOC please keep comment here to allow auto update -->
<!-- DON'T EDIT THIS SECTION, INSTEAD RE-RUN doctoc TO UPDATE -->
**Table of Contents** *generated with [DocToc](https://github.com/thlorenz/doctoc)*

- [hash](#hash)
- [hashMap](#hashmap)
- [结构](#%E7%BB%93%E6%9E%84)
- [扩容和缩容](#%E6%89%A9%E5%AE%B9%E5%92%8C%E7%BC%A9%E5%AE%B9)
- [HashSet](#hashset)

<!-- END doctoc generated TOC please keep comment here to allow auto update -->

# hash

## hashMap
Expand Down
11 changes: 11 additions & 0 deletions chapter10-error/error.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,14 @@
<!-- START doctoc generated TOC please keep comment here to allow auto update -->
<!-- DON'T EDIT THIS SECTION, INSTEAD RE-RUN doctoc TO UPDATE -->
**Table of Contents** *generated with [DocToc](https://github.com/thlorenz/doctoc)*

- [error](#error)
- [? 操作符](#-%E6%93%8D%E4%BD%9C%E7%AC%A6)
- [Error trait 和错误类型的转换](#error-trait-%E5%92%8C%E9%94%99%E8%AF%AF%E7%B1%BB%E5%9E%8B%E7%9A%84%E8%BD%AC%E6%8D%A2)
- [thiserror](#thiserror)

<!-- END doctoc generated TOC please keep comment here to allow auto update -->

# error

![img.png](error-situation.png)
Expand Down
12 changes: 11 additions & 1 deletion chapter11-closure/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -14,4 +14,14 @@ path = "src/closure1-size.rs"

[[bin]]
name = "closure2"
path = "src/closure2-fnonce.rs"
path = "src/closure2-fnonce.rs"


[[bin]]
name = "closure3"
path = "src/closure3-fnmut.rs"


[[bin]]
name = "closure4"
path = "src/closure4-fn.rs"
Binary file added chapter11-closure/closure-type.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
50 changes: 49 additions & 1 deletion chapter11-closure/closure.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,16 @@
<!-- START doctoc generated TOC please keep comment here to allow auto update -->
<!-- DON'T EDIT THIS SECTION, INSTEAD RE-RUN doctoc TO UPDATE -->
**Table of Contents** *generated with [DocToc](https://github.com/thlorenz/doctoc)*

- [闭包](#%E9%97%AD%E5%8C%85)
- [案例](#%E6%A1%88%E4%BE%8B)
- [Rust 的闭包类型](#rust-%E7%9A%84%E9%97%AD%E5%8C%85%E7%B1%BB%E5%9E%8B)
- [FnOnce 只能被调用一次](#fnonce-%E5%8F%AA%E8%83%BD%E8%A2%AB%E8%B0%83%E7%94%A8%E4%B8%80%E6%AC%A1)
- [FnMut](#fnmut)
- [Fn](#fn)

<!-- END doctoc generated TOC please keep comment here to allow auto update -->

# 闭包

> A closure expression produces a closure value with a unique, anonymous type that cannot be written out.
Expand Down Expand Up @@ -25,6 +38,8 @@ where

## Rust 的闭包类型

![img.png](closure-type.png)

### FnOnce 只能被调用一次

```rust
Expand All @@ -43,4 +58,37 @@ pub trait FnOnce<Args: Tuple> {
}
```

call_once 第一个参数是 self,它会转移 self 的所有权到 call_once 函数中
call_once 第一个参数是 self,它会转移 self 的所有权到 call_once 函数中

### FnMut

```rust
#[fundamental] // so that regex can rely that `&str: !FnMut`
#[must_use = "closures are lazy and do nothing unless called"]
// FIXME(effects) #[const_trait]
pub trait FnMut<Args: Tuple>: FnOnce<Args> {
/// Performs the call operation.
#[unstable(feature = "fn_traits", issue = "29625")]
extern "rust-call" fn call_mut(&mut self, args: Args) -> Self::Output;
}

```

FnOnce 是 FnMut 的 super trait。所以 FnMut 也拥有 Output 这个关联类型和 call_once 这个方法。
此外,它还有一个 call_mut() 方法。注意 call_mut() 传入 &mut self,它不移动 self,所以 FnMut 可以被多次调用。

### Fn

```rust
#[fundamental] // so that regex can rely that `&str: !FnMut`
#[must_use = "closures are lazy and do nothing unless called"]
// FIXME(effects) #[const_trait]
pub trait Fn<Args: Tuple>: FnMut<Args> {
/// Performs the call operation.
#[unstable(feature = "fn_traits", issue = "29625")]
extern "rust-call" fn call(&self, args: Args) -> Self::Output;
}

```

Fn “继承”了 FnMut
4 changes: 2 additions & 2 deletions chapter11-closure/src/closure1-size.rs
Original file line number Diff line number Diff line change
@@ -1,11 +1,10 @@
mod r#closure2

use std::{collections::HashMap, mem::size_of_val};
fn main() {
// 长度为 0
let c1 = || println!("hello world!");
// 和参数无关,长度也为 0
let c2 = |i: i32| println!("hello: {}", i);

let name = String::from("Danny");
let name1 = name.clone();
let mut table = HashMap::new();
Expand All @@ -14,6 +13,7 @@ fn main() {
let c3 = || println!("hello: {}", name);
// 捕获移动的数据 name1(长度 24) + table(长度 48),closure 长度 72
let c4 = move || println!("hello: {}, {:?}", name1, table);

let name2 = name.clone();
// 和局部变量无关,捕获了一个 String name2,closure 长度 24
let c5 = move || {
Expand Down
35 changes: 35 additions & 0 deletions chapter11-closure/src/closure3-fnmut.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
fn main() {
let mut name = String::from("hello");
let mut name1 = String::from("hola");

// 捕获 &mut name
let mut c = || {
name.push_str(" Danny");
println!("c: {}", name);
};

// 捕获 mut name1,注意 name1 需要声明成 mut
let mut c1 = move || {
name1.push_str("!");
println!("c1: {}", name1);
};

c();
c1();

call_mut(&mut c);
call_mut(&mut c1);

call_once(c);
call_once(c1);
}

// 在作为参数时,FnMut 也要显式地使用 mut,或者 &mut
fn call_mut(c: &mut impl FnMut()) {
c();
}

// 想想看,为啥 call_once 不需要 mut?
fn call_once(c: impl FnOnce()) {
c();
}
33 changes: 33 additions & 0 deletions chapter11-closure/src/closure4-fn.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
fn main() {
let v = vec![0u8; 1024];
let v1 = vec![0u8; 1023];

// Fn,不移动所有权
let mut c = |x: u64| v.len() as u64 * x;
// Fn,移动所有权
let mut c1 = move |x: u64| v1.len() as u64 * x;

println!("direct call: {}", c(2));
println!("direct call: {}", c1(2));

println!("call: {}", call(3, &c));
println!("call: {}", call(3, &c1));

println!("call_mut: {}", call_mut(4, &mut c));
println!("call_mut: {}", call_mut(4, &mut c1));

println!("call_once: {}", call_once(5, c));
println!("call_once: {}", call_once(5, c1));
}

fn call(arg: u64, c: &impl Fn(u64) -> u64) -> u64 {
c(arg)
}

fn call_mut(arg: u64, c: &mut impl FnMut(u64) -> u64) -> u64 {
c(arg)
}

fn call_once(arg: u64, c: impl FnOnce(u64) -> u64) -> u64 {
c(arg)
}
11 changes: 11 additions & 0 deletions chapter12-unsafe/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
[package]
name = "chapter12-unsafe"
version.workspace = true
edition.workspace = true
authors.workspace = true


[[bin]]
name = "unsafe1"
path = "src/unsafe1-caller.rs"

Loading

0 comments on commit 70ccf33

Please sign in to comment.