Merge pull request #8 from sunface/main

sync
pull/807/head
Rustln 3 years ago committed by GitHub
commit dd6e1f5074
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -6,7 +6,7 @@
<div align="center">
[![studyrut](https://img.shields.io/badge/Rust语言中文网-orange)](https://github.com/rustlang-cn) [![Stars Count](https://img.shields.io/github/stars/sunface/rust-course?style=flat)](https://github.com/sunface/rust-course/stargazers)
[![studyrut](https://img.shields.io/badge/RustCn-orange)](https://github.com/rustlang-cn) [![Stars Count](https://img.shields.io/github/stars/sunface/rust-course?style=flat)](https://github.com/sunface/rust-course/stargazers)
[![](https://img.shields.io/github/issues-pr-closed-raw/sunface/rust-course.svg?style=flat)](https://github.com/sunface/rust-course/issues)
[![Binder](https://mybinder.org/badge_logo.svg)](https://mybinder.org/v2/gh/ines/spacy-course/master)
@ -150,7 +150,7 @@
- 知乎: [孙飞 Sunface](https://www.zhihu.com/people/iSunface)
- QQ群 `1009730433`,用于日常技术交流
- 微信公众号: 搜索 `studyrust`扫描下面的二维码关注公众号 `Rust语言中文网`
- 微信公众号: 扫描下面的二维码关注公众号 `Rust语言中文网`
<img src="https://github.com/sunface/rust-course/blob/main/assets/studyrust公众号.png?raw=true" />

@ -20,7 +20,7 @@
- [下载依赖太慢了?](first-try/slowly-downloading.md)
- [避免从入门到放弃](first-try/sth-you-should-not-do.md)
# Rust语言特性
# Rust语言学习
---
- [Rust 基础入门](basic/intro.md)
- [变量绑定与解构](basic/variable.md)
@ -103,14 +103,6 @@
<!-- - [SIMD todo](advance/simd.md) -->
<!-- - [高阶特征约束(HRTB) todo](advance/hrtb.md) -->
- [易混淆概念解析](advance/confonding/intro.md)
- [切片和切片引用](advance/confonding/slice.md)
- [Eq 和 PartialEq](advance/confonding/eq.md)
- [String、&str 和 str todo](advance/confonding/string.md)
- [裸指针、引用和智能指针 todo](advance/confonding/pointer.md)
- [作用域、生命周期和 NLL todo](advance/confonding/lifetime.md)
- [move、Copy 和 Clone todo](advance/confonding/move-copy.md)
- [Rust 异步编程](async-rust/intro.md)
- [async/await 异步编程](async-rust/async/intro.md)
- [async 编程入门](async-rust/async/getting-started.md)
@ -133,7 +125,18 @@
- [类似迭代器的 Stream](async-rust/tokio/stream.md))
- [优雅的关闭](async-rust/tokio/graceful-shutdown.md)
- [异步跟同步共存](async-rust/tokio/bridging-with-sync.md)
- [Rust 难点攻关](difficulties/intro.md)
- [切片和切片引用](difficulties/slice.md)
- [Eq 和 PartialEq](difficulties/eq.md)
- [String、&str 和 str TODO](difficulties/string.md)
- [作用域、生命周期和 NLL TODO](difficulties/lifetime.md)
- [move、Copy 和 Clone TODO](difficulties/move-copy.md)
- [裸指针、引用和智能指针 TODO](advance/difficulties/pointer.md)
# 常用工具链
---
- [自动化测试](test/intro.md)

@ -1,5 +0,0 @@
# 易混淆概念解析
Rust 之所以难,有部分原因在于一些概念对于刚入门的同学来说不仅难以理解,还容易混淆。
对于难以理解这一点,我们在之前的章节已经讲解的差不多。本章就来看看,那些容易混淆的概念该如何进行区分,例如 `String`、`str` 和 `&str`

@ -1 +0,0 @@
# 裸指针、引用和智能指针 todo

@ -0,0 +1 @@
# 裸指针、引用和智能指针 TODO

@ -31,7 +31,7 @@ fn my_function(n: usize) {
#### 切片
切片也是一个典型的 DST 类型,具体详情参见另一篇文章: [易混淆的切片和切片引用](https://course.rs/confonding/slice.html)。
切片也是一个典型的 DST 类型,具体详情参见另一篇文章: [易混淆的切片和切片引用](https://course.rs/difficulties/slice.html)。
#### str

@ -16,7 +16,7 @@ fn print_author(author: &'static str) {
}
```
除此之外,特征对象的生命周期也是 `'static`,例如[这里](https://course.rs/fight-with-compiler/lifetime/closure-with-static.html#特征对象的生命周期)所提到的。
除此之外,特征对象的生命周期也是 `'static`,例如[这里](https://course.rs/compiler/fight-with-compiler/lifetime/closure-with-static.html#特征对象的生命周期)所提到的。
除了 `&'static` 的用法外,我们在另外一种场景中也可以见到 `'static` 的使用:

@ -72,9 +72,9 @@ Rust 语言的安全可靠性顺理成章的影响了 `tokio` 的可靠性,曾
虽然 `tokio` 对于大多数需要并发的项目都是非常适合的,但是确实有一些场景它并不适合使用:
- 并行运行 CPU 密集型的任务,`tokio` 非常适合于 IO 密集型任务,这些 IO 任务的绝大多数时间都用于阻塞等待 IO 的结果,而不是刷刷刷的单烤 CPU。如果你的应用是 CPU 密集型(例如并行计算),建议使用 [`rayon`](https://github.com/rayon-rs/rayon),当然,对于其中的 IO 任务部分,你依然可以混用 `tokio`
- 读取大量的文件, 读取文件的瓶颈主要在于操作系统,因为 OS 没有提供异步文件读取接口,大量的并发并不会提升文件读取的并行性能,反而可能会造成不可忽视的性能损耗,因此建议使用线程(或线程池)的方式
- 发送 HTTP 请求,`tokio` 的优势是给予你并发处理大量任务的能力,对于这种轻量级 HTTP 请求场景,`tokio` 除了增加你的代码复杂性,并无法带来什么额外的优势。因此,对于这种场景,你可以使用 [`reqwest`](https://github.com/seanmonstar/reqwest) 库,它会更加简单易用。
- **并行运行 CPU 密集型的任务**。`tokio` 非常适合于 IO 密集型任务,这些 IO 任务的绝大多数时间都用于阻塞等待 IO 的结果,而不是刷刷刷的单烤 CPU。如果你的应用是 CPU 密集型(例如并行计算),建议使用 [`rayon`](https://github.com/rayon-rs/rayon),当然,对于其中的 IO 任务部分,你依然可以混用 `tokio`
- **读取大量的文件**。读取文件的瓶颈主要在于操作系统,因为 OS 没有提供异步文件读取接口,大量的并发并不会提升文件读取的并行性能,反而可能会造成不可忽视的性能损耗,因此建议使用线程(或线程池)的方式
- **发送少量 HTTP 请求**。`tokio` 的优势是给予你并发处理大量任务的能力,对于这种轻量级 HTTP 请求场景,`tokio` 除了增加你的代码复杂性,并无法带来什么额外的优势。因此,对于这种场景,你可以使用 [`reqwest`](https://github.com/seanmonstar/reqwest) 库,它会更加简单易用。
> 若大家使用 tokio那 CPU 密集的任务尤其需要用线程的方式去处理,例如使用 `spawn_blocking` 创建一个阻塞的线程取完成相应 CPU 密集任务。

@ -6,7 +6,7 @@
object.method()
```
例如读取一个文件写入缓冲区,如果用函数的写法 `read(f,buffer)`,用方法的写法 `f.read(buffer)`。不过与其它语言 `class` 跟方法的联动使用不同这里可能要修改下Rust 的方法往往跟结构体、枚举、特征一起使用,特征(Trait)将在后面几章进行介绍。
例如读取一个文件写入缓冲区,如果用函数的写法 `read(f, buffer)`,用方法的写法 `f.read(buffer)`。不过与其它语言 `class` 跟方法的联动使用不同这里可能要修改下Rust 的方法往往跟结构体、枚举、特征(Trait)一起使用,特征将在后面几章进行介绍。
## 定义方法
@ -73,6 +73,7 @@ fn main() {
`impl Rectangle {}` 表示为 `Rectangle` 实现方法(`impl` 是实现 _implementation_ 的缩写),这样的写法表明 `impl` 语句块中的一切都是跟 `Rectangle` 相关联的。
#### self、&self 和 &mut self
接下里的内容非常重要,请大家仔细看。在 `area` 的签名中,我们使用 `&self` 替代 `rectangle: &Rectangle``&self` 其实是 `self: &Self` 的简写(注意大小写)。在一个 `impl` 块内,`Self` 指代被实现方法的结构体类型,`self` 指代此类型的实例,换句话说,`self` 指代的是 `Rectangle` 结构体实例,这样的写法会让我们的代码简洁很多,而且非常便于理解:我们为哪个结构体实现方法,那么 `self` 就是指代哪个结构体的实例。
需要注意的是,`self` 依然有所有权的概念:
@ -113,7 +114,7 @@ fn main() {
}
```
当我们使用 `rect1.width()` 时, Rust 知道我们调用的是它的方法,如果使用 `rect1.width`,则是访问它的字段。
当我们使用 `rect1.width()`Rust 知道我们调用的是它的方法,如果使用 `rect1.width`,则是访问它的字段。
一般来说,方法跟字段同名,往往适用于实现 `getter` 访问器,例如:
@ -221,7 +222,7 @@ impl Rectangle {
> Rust 中有一个约定俗称的规则,使用 `new` 来作为构造器的名称出于设计上的考虑Rust 特地没有用 `new` 作为关键字
因为是函数,所以不能用 `.` 的方式来调用,我们需要用`::`来调用,例如 `let sq = Rectangle::new(3,3);`。这个方法位于结构体的命名空间中:`::` 语法用于关联函数和模块创建的命名空间。
因为是函数,所以不能用 `.` 的方式来调用,我们需要用 `::` 来调用,例如 `let sq = Rectangle::new(3, 3);`。这个方法位于结构体的命名空间中:`::` 语法用于关联函数和模块创建的命名空间。
## 多个 impl 定义
@ -276,7 +277,6 @@ m.call();
除了结构体和枚举,我们还能为特征(trait)实现方法,这将在下一章进行讲解,在此之前,先来看看泛型。
## 课后练习
> [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)。

@ -0,0 +1,14 @@
# Rust 难点攻关
当大家一路看到这里时,我敢说 90% 的人还是云里雾里的,例如你能说清楚:
- 切片和切片引用的区别吗?
- 各种字符串之间的区别吗?
- 各种指针、引用的区别吗?
- 所有权转移、拷贝、克隆的区别吗?
以及到底该用它们之中哪一个吗?
如果不行,就跟随我一起来看看吧,本章的目标就是帮大家彻底理清这些概念,为后面的进一步学习和实战打好坚实的基础。

@ -0,0 +1,3 @@
# 裸指针、引用和智能指针 todo
<!-- https://blog.csdn.net/kk3909/article/details/106743025 -->

@ -47,7 +47,7 @@ time = { registry = "ustc" }
#### 覆盖默认的镜像地址
事实上,我们更推荐第二种方式,因为第一种方式在项目大了后,实在是很麻烦,全部修改后,万一以后不用这个镜像了,你又要全部修改成其它的。
而第二种方式,则不需要修改 `Cargo.toml` 文件,因为它**因为它是直接使用新注册服务来替代默认的 `crates.io`**。
而第二种方式,则不需要修改 `Cargo.toml` 文件,**因为它是直接使用新注册服务来替代默认的 `crates.io`**。
```toml
[source.crates-io]

@ -10,11 +10,13 @@
<a id="head"></a>
| NN | NN | NN | NN | NN | NN | NN | NN | NN |
| :---------: | :-----: | :-----: | :-----: | :-----: | :-----: | :-----: | :-----: | :-----: |
| [Sym](#sym) | [A](#a) | [B](#b) | [C](#c) | [D](#d) | [E](#e) | [F](#f) | [G](#g) | [H](#h) |
| [I](#i) | [J](#j) | [K](#k) | [L](#l) | [M](#m) | [N](#n) | [O](#o) | [P](#p) | [Q](#q) |
| [R](#r) | [S](#s) | [T](#t) | [U](#u) | [V](#v) | [W](#w) | [X](#x) | [Y](#y) | [Z](#z) |
| NN | NN | NN | NN | NN | NN | NN | NN | NN | NN | NN | NN |
| :-------------: | :-----: | :-----: | :-----: | :-----: | :-----: | :-----: | :-----: | :-----: | :-----: | :-----: | :-----: |
| [Sym](#sym) | [A](#a) | [B](#b) | [C](#c) | [D](#d) | [E](#e) | [F](#f) | [G](#g) | [H](#h) | [I](#i) | [J](#j) | [K](#k) |
| [Cargo](#cargo) | [L](#l) | [M](#m) | [N](#n) | [O](#o) | [P](#p) | [Q](#q) | [R](#r) | [S](#s) | [T](#t) | [U](#u) | [V](#v) |
| [W](#w) | [X](#x) | [Y](#y) | [Z](#z) |
[bottom](#bottom)
## Sym
@ -29,6 +31,7 @@
| `_` : [1 忽略变量] [2 模式匹配] | 忽略 | 1. 忽略该值或者类型,否则编译器会给你一个 `变量未使用的` 的警告<br>2. 模式匹配通配符 |
| ['a: 'b] | 生命周期约束 | 用来说明两个生命周期的长短 |
| [{:?}] {:#?} | 打印结构体信息 | 使用 `#[derive(Debug)]` 派生实现 `Debug` 特征 |
| [::] | 关联函数 | 定义在 `impl` 中且没有 `self` 的函数 |
| A | | AIntroduction |
[?]: https://course.rs/basic/result-error/result.html#传播界的大明星-
@ -42,6 +45,7 @@
[{:?}]: https://course.rs/basic/compound-type/struct.html?search=#使用-derivedebug-来打印结构体的信息
[1 忽略变量]: https://course.rs/basic/variable.html#使用下划线开头忽略未使用的变量
[2 模式匹配]: https://course.rs/basic/match-pattern/match-if-let.html#_-通配符
[::]: https://course.rs/basic/method.html#关联函数
[back](#head)
@ -108,12 +112,14 @@
## E
| 名称 | 关键字 | 简介 |
| ----------- | -------- | ---------------------------------------- |
| [enum 枚举] | 枚举类型 | 允许通过列举可能的成员来定义一个枚举类型 |
| E | KWE | EIntroduction |
| 名称 | 关键字 | 简介 |
| ----------------- | -------- | ---------------------------------------- |
| [enum 枚举] | 枚举类型 | 允许通过列举可能的成员来定义一个枚举类型 |
| [enum 同一化类型] | 枚举方法 | 枚举实现方法 |
| E | KWE | EIntroduction |
[enum 枚举]: https://course.rs/basic/compound-type/enum.html#枚举
[enum 同一化类型]: https://course.rs/basic/compound-type/enum.html#同一化类型
[back](#head)
@ -198,15 +204,17 @@
## M
| 名称 | 关键字 | 简介 |
| ------------- | ---------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| [模式绑定] | 模式匹配 | 从模式中取出绑定的值 |
| [全模式列表] | 模式匹配 | 列出了所有的模式匹配 |
| [match 匹配] | 模式匹配 | `match` 的匹配必须要穷举出所有可能,因此这里用 `_ ` 来代表未列出的所有可能性<br>`match` 的每一个分支都必须是一个表达式,且所有分支的表达式最终返回值的类型必须相同 |
| [matches! 宏] | 模式匹配 | 将一个表达式跟模式进行匹配,然后返回匹配的结果 `true``false` |
| [match guard] | 匹配守卫 | 位于 `match` 分支模式之后的额外 `if` 条件,它能为分支模式提供更进一步的匹配条件 |
| [move 移动] | 转移所有权 | `let s2 = s1;`<br>`s1` 所有权转移给了 `s2``s1` 失效 |
| M | KWM | MIntroduction |
| 名称 | 关键字 | 简介 |
| --------------- | ---------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| [模式绑定] | 模式匹配 | 从模式中取出绑定的值 |
| [全模式列表] | 模式匹配 | 列出了所有的模式匹配 |
| [Method 方法] | `impl` | Rust 的方法往往跟结构体、枚举、特征一起使用 |
| [Method getter] | `getter` | 方法名跟结构体的字段名相同 |
| [match 匹配] | 模式匹配 | `match` 的匹配必须要穷举出所有可能,因此这里用 `_ ` 来代表未列出的所有可能性<br>`match` 的每一个分支都必须是一个表达式,且所有分支的表达式最终返回值的类型必须相同 |
| [matches! 宏] | 模式匹配 | 将一个表达式跟模式进行匹配,然后返回匹配的结果 `true``false` |
| [match guard] | 匹配守卫 | 位于 `match` 分支模式之后的额外 `if` 条件,它能为分支模式提供更进一步的匹配条件 |
| [move 移动] | 转移所有权 | `let s2 = s1;`<br>`s1` 所有权转移给了 `s2``s1` 失效 |
| M | KWM | MIntroduction |
[模式绑定]: https://course.rs/basic/match-pattern/match-if-let.html#模式绑定
[match 匹配]: https://course.rs/basic/match-pattern/match-if-let.html#match-匹配
@ -214,6 +222,8 @@
[move 移动]: https://course.rs/basic/ownership/ownership.html#转移所有权
[全模式列表]: https://course.rs/basic/match-pattern/all-patterns.html
[match guard]: https://course.rs/basic/match-pattern/all-patterns.html#匹配守卫提供的额外条件
[method 方法]: https://course.rs/basic/method.html#定义方法
[method getter]: https://course.rs/basic/method.html#方法名跟结构体字段名相同
[back](#head)
@ -267,16 +277,17 @@
## S
| 名称 | 关键字 | 简介 |
| --------------- | ------------- | ------------------------------------------------------------------------------------------------------------------------ |
| [所有权与堆栈] | | Rust 所有权提供的强大保障 |
| [所有权原则] | | Rust 中每一个值都 `有且只有` 一个所有者(变量)<br> 当所有者(变量)离开作用域范围时,这个值将被丢弃(drop) |
| [slice 切片] | `&str` | 允许你引用 `String` 中部分连续的元素序列,而不是引用整个 `String` <br>语法:`[开始索引..终止索引]`<br>字符串字面量是切片 |
| [String 字符串] | `String` 类型 | Rust 中的字符串是 UTF-8 编码,也就是字符串中的字符所占的字节数是变化的(1 - 4) |
| [String 操作] | `String` 方法 | 由于 `String` 是可变字符串,因此我们可以对它进行创建、增删操作 |
| [String 转义] | `String` 方法 | 通过转义的方式 `\` 输出 ASCII 和 Unicode 字符 |
| [struct 结构体] | 结构体 | 通过关键字 `struct` 定义<br>一个清晰明确的结构体 `名称`<br>几个有名字的结构体 `字段`<br>通过 `.` 访问字段 |
| S | KWS | SIntroduction |
| 名称 | 关键字 | 简介 |
| ---------------------- | ------------- | ------------------------------------------------------------------------------------------------------------------------ |
| [所有权与堆栈] | | Rust 所有权提供的强大保障 |
| [所有权原则] | | Rust 中每一个值都 `有且只有` 一个所有者(变量)<br> 当所有者(变量)离开作用域范围时,这个值将被丢弃(drop) |
| [slice 切片] | `&str` | 允许你引用 `String` 中部分连续的元素序列,而不是引用整个 `String` <br>语法:`[开始索引..终止索引]`<br>字符串字面量是切片 |
| [String 字符串] | `String` 类型 | Rust 中的字符串是 UTF-8 编码,也就是字符串中的字符所占的字节数是变化的(1 - 4) |
| [String 操作] | `String` 方法 | 由于 `String` 是可变字符串,因此我们可以对它进行创建、增删操作 |
| [String 转义] | `String` 方法 | 通过转义的方式 `\` 输出 ASCII 和 Unicode 字符 |
| [struct 结构体] | 结构体 | 通过关键字 `struct` 定义<br>一个清晰明确的结构体 `名称`<br>几个有名字的结构体 `字段`<br>通过 `.` 访问字段 |
| [self &self &mut self] | Method 方法 | `self` 指代类型的实例 |
| S | KWS | SIntroduction |
[所有权与堆栈]: https://course.rs/basic/ownership/ownership.html#所有权与堆栈
[所有权原则]: https://course.rs/basic/ownership/ownership.html#所有权原则
@ -285,6 +296,7 @@
[string 操作]: https://course.rs/basic/compound-type/string-slice.html#操作字符串
[string 转义]: https://course.rs/basic/compound-type/string-slice.html#字符串转义
[struct 结构体]: https://course.rs/basic/compound-type/struct.html
[self &self &mut self]: https://course.rs/basic/method.html#selfself-和-mut-self
[back](#head)
@ -363,3 +375,12 @@
[back](#head)
## Cargo
| 名称 | 关键字 | 简介 |
| ----- | ------ | -------------- |
| Cargo | KWCG | CGIntroduction |
[back](#head)
<a id="bottom"></a>

@ -1,6 +1,6 @@
# 日志门面 log
就如同 slf4j 是 Java 的日志门面库,[log](https://github.com/rust-lang/log) 也是 Rust 的日志门面库( 这不是我自己编的,官方用语: logging facade ),它目前是由官方提供维护工作,更新较为活跃,因此大家可以放心使用。
就如同 slf4j 是 Java 的日志门面库,[log](https://github.com/rust-lang/log) 也是 Rust 的日志门面库( 这不是我自己编的,官方用语: logging facade ),它目前由官方积极维护,因此大家可以放心使用。
使用方式很简单,只要在 `Cargo.toml` 中引入即可:
```toml
@ -29,7 +29,7 @@ pub trait Log: Sync + Send {
## 日志宏
`log` 还为我们提供了一整套标准的宏,用于方便地记录日志。`trace!`、`debug!`、`info!`、`warn!`、`error!`,这几个大家是否很眼熟,是的,它们跟我们上一章节提到的日志级别几乎一模一样,唯一的区别就是这里乱入了一个 `trace!`,它比 `debug!` 的日志级别还要低、记录的信息还要详细,这么说吧,如果你想事无巨细的追踪某个流程的所有信息,就可以用它了
`log` 还为我们提供了一整套标准的宏,用于方便地记录日志。看到 `trace!`、`debug!`、`info!`、`warn!`、`error!`,大家是否感觉眼熟呢?是的,它们跟上一章节提到的日志级别几乎一模一样,唯一的区别就是这里乱入了一个 `trace!`,它比 `debug!` 的日志级别还要低,记录的信息还要详细。可以说,你如果想巨细无遗地了解某个流程的所有踪迹,它就是不二之选
```rust
use log::{info, trace, warn};
@ -54,7 +54,7 @@ pub fn shave_the_yak(yak: &mut Yak) {
上面的例子使用 `trace!` 记录了一条可有可无的信息:准备开始剃须,然后开始寻找剃须刀,找到后就用 `info!` 记录一条可能事后也没人看的信息:找到剃须刀;没找到的话,就记录一条 `warn!` 信息,这条信息就有一定价值了,不仅告诉我们没找到的原因,还记录了发生的次数,有助于事后定位问题。
可以看出,这里的日志级别使用跟我们上一章节描述的基本吻合
可以看出,这里使用日志级别的方式和我们上一章节所述基本相符
除了以上常用的,`log` 还提供了 `log!``log_enabled!` 宏,后者用于确定一条消息在当前模块中,对于给定的日志级别是否能够被记录

@ -45,17 +45,15 @@
* [rbatis/rbatis](https://github.com/rbatis/rbatis) 国内团队开发的ORM异步、性能高、简单易上手
* [diesel-rs/diesel](https://github.com/diesel-rs/diesel) 安全、扩展性强的Rust ORM库支持`Mysql`、`Postgre`、`SqlLite`
* Mysql
* MySQL
* [blackbeam/rust-mysql-simple](https://github.com/blackbeam/rust-mysql-simple) 纯Rust实现的Mysql驱动,提供连接池
* [blackbeam/mysql_async](https://github.com/blackbeam/mysql_async) 基于Tokio实现的异步Mysql驱动
* 上面两个都是一个团队出品前者文档更全、star更多建议使用前者
* Postgre
* PostgreSQL
* [sfackler/rust-postgres](https://github.com/sfackler/rust-postgres) 纯Rust实现的Postgre客户端
* Sqlite
* SQLite
* [rusqlite](https://github.com/rusqlite/rusqlite) 用于[Sqlite3](https://www.sqlite.org/index.html)的Rust客户端
### NoSql客户端
@ -67,7 +65,6 @@
* [krojew/cdrs-tokio](https://github.com/krojew/cdrs-tokio) [[cdrs-tokio](https://crates.io/crates/cdrs-tokio)] 生产可用的Cassandra客户端异步、纯Rust实现就是个人项目 + star较少未来不确定会不会不维护
* [scylla-rust-driver](https://github.com/scylladb/scylla-rust-driver) ScyllaDB提供的官方库支持cql协议由于背靠大山未来非常可期
* MongoDB
* [mongodb/mongo-rust-driver](https://github.com/mongodb/mongo-rust-driver) 官方MongoDB客户端闭着眼睛选就对了
@ -83,17 +80,20 @@
* [nats-io/nats.rs](https://github.com/nats-io/nats.rs) Nats官方提供的客户端
### 网络、通信协议
* Websocket
* WebSocket
* [snapview/tokio-tungstenite](https://github.com/snapview/tokio-tungstenite) 更适合Web应用使用的生产级Websocket库它是异步非阻塞的基于下面的`tungstenite-rs`库和tokio实现
* [rust-websocket](https://github.com/websockets-rs/rust-websocket) 老牌Websocket库提供了客户端和服务器端实现但是。。。很久没更新了
* [snapview/tungstenite-rs](https://github.com/snapview/tungstenite-rs) 轻量级的Websocket流实现该库更偏底层例如你可以用来构建其它网络库
* gRPC
* [hyperium/tonic](https://github.com/hyperium/tonic) 纯Rust实现的gRPC客户端和服务器端支持async/await异步调用文档和示例较为清晰
* [tikv/grpc-rs](https://github.com/tikv/grpc-rs) 国产开源之光Tidb团队出品的gRPC框架, 基于C的代码实现, 就是最近好像不是很活跃
* 其实这两个实现都很优秀,把`tonic`放在第一位主要是因为它是纯Rust实现同时社区也更为活跃但是并不代表它比`tikv`的更好!
* QUIC
* [cloudflare/quiche](https://github.com/cloudflare/quiche) 大名鼎鼎`cloudflare`提供的QUIC实现据说在公司内部重度使用有了大规模生产级别的验证非常值得信任同时该库还实现了HTTP/3
* [quinn-rs/quinn](https://github.com/quinn-rs/quinn) 提供异步API调用纯Rust实现同时提供了几个有用的网络库
* MQTT
* [bytebeamio/rumqtt](https://github.com/bytebeamio/rumqtt) MQTT3.1.1/5协议库同时实现了客户端与服务器端broker
* [ntex-rs/ntex-mqtt](https://github.com/ntex-rs/ntex-mqtt) 客户端与服务端框架支持MQTT3.1.1与5协议
@ -123,6 +123,7 @@
### 代码Debug
* GDB
* [gdbgui](https://github.com/cs01/gdbgui) 提供浏览器支持的gdb debug工具支持CC++Rust和Go.
* LLDB
* [CodeLLDB](https://marketplace.visualstudio.com/items?itemName=vadimcn.vscode-lldb) — 专门为VSCode设计的LLDB Debug扩展
@ -137,17 +138,23 @@
* [Serde](https://github.com/serde-rs/serde) 一个超高性能的通用序列化/反序列化框架,可以跟多种协议的库联合使用,实现统一编解码格式
* CSV
* [BurntSushi/rust-csv](https://github.com/BurntSushi/rust-csv) 高性能CSV读写库支持[Serde](https://github.com/serde-rs/serde)
* JSON
* [serde-rs/json](https://github.com/serde-rs/json) 快到上天的JSON库也是Rust事实上的标准JSON库你也可以使用它的大哥[serde](https://github.com/serde-rs/serde),一个更通用的序列化/反序列化库
* MsgPack
* [3Hren/msgpack-rust](https://github.com/3Hren/msgpack-rust) 纯Rust实现的MessagePack编解码协议
* ProtocolBuffers
* Protocol Buffers
* [tokio-rs/prost](https://github.com/tokio-rs/prost) tokio出品基本都属精品此库也不例外简单易用文档详细
* [stepancheg/rust-protobuf](https://github.com/stepancheg/rust-protobuf) 纯Rust实现
* TOML
* [alexcrichton/toml-rs](https://github.com/alexcrichton/toml-rs) TOML编码/解码,可以配合`serde`使用
* XML
* [tafia/quick-xml](https://github.com/tafia/quick-xml) 高性能XML库可以配合`serde`使用,文档较为详细
* YAML
* [dtolnay/serde-yaml](https://github.com/dtolnay/serde-yaml) 使用`serde`编解码`YAML`格式的数据
@ -155,6 +162,3 @@
* [lettre/lettre](https://github.com/lettre/lettre) — Rust SMTP库
### 常用正则模版

Loading…
Cancel
Save