diff --git a/src/safe-guides/coding_practice/async-await/G.ASY.01.md b/src/safe-guides/coding_practice/async-await/G.ASY.01.md index 213c0cf1..95504633 100644 --- a/src/safe-guides/coding_practice/async-await/G.ASY.01.md +++ b/src/safe-guides/coding_practice/async-await/G.ASY.01.md @@ -4,7 +4,7 @@ **【描述】** - 略。 +在此条件下 `.await` 语句通常为必须的。 **【反例】** diff --git a/src/safe-guides/coding_practice/async-await/G.ASY.03.md b/src/safe-guides/coding_practice/async-await/G.ASY.03.md index 8453b061..cdb509cf 100644 --- a/src/safe-guides/coding_practice/async-await/G.ASY.03.md +++ b/src/safe-guides/coding_practice/async-await/G.ASY.03.md @@ -1,6 +1,6 @@ ## G.ASY.03 在跨 `await` 调用中,需要对其持有 `RefCell` 的引用进行处理 -**【级别:建议】** +**【级别】** 建议 **【描述】** diff --git a/src/safe-guides/coding_practice/cargo/G.CAR.01.md b/src/safe-guides/coding_practice/cargo/G.CAR.01.md index 62ec5f43..cbd8713c 100644 --- a/src/safe-guides/coding_practice/cargo/G.CAR.01.md +++ b/src/safe-guides/coding_practice/cargo/G.CAR.01.md @@ -24,7 +24,7 @@ bin/ 这样的好处有: 1. 便于单元测试。 -2. 这样拆分有利于面向接口思考,让代码架构和逻辑更加清晰。 +2. 有利于面向接口思考,让代码架构和逻辑更加清晰。 若编写的可执行程序比较复杂,在 `main.rs` 里需要依赖太多东西时,那就需要创建 Workspace 把 `main.rs` 独立为一个 crate,而在这个 crate 内也没有必要再拆分为 `main` 和 `lib` 了。 diff --git a/src/safe-guides/coding_practice/cargo/G.CAR.02.md b/src/safe-guides/coding_practice/cargo/G.CAR.02.md index fd095d9e..05e2d1d1 100644 --- a/src/safe-guides/coding_practice/cargo/G.CAR.02.md +++ b/src/safe-guides/coding_practice/cargo/G.CAR.02.md @@ -10,7 +10,7 @@ **【反例】** ```toml -# This `Cargo.toml` is missing a description field: +# 此 `Cargo.toml` 缺失介绍(description)项。无法发布到 crates.io。 [package] name = "clippy" version = "0.0.212" @@ -24,7 +24,7 @@ categories = ["development-tools", "development-tools::cargo-plugins"] **【正例】** ```toml -# This `Cargo.toml` includes all common metadata +# 此 `Cargo.toml` 包含必要元信息。 [package] name = "clippy" version = "0.0.212" diff --git a/src/safe-guides/coding_practice/cargo/P.CAR.01.md b/src/safe-guides/coding_practice/cargo/P.CAR.01.md index e3c9b410..21ac5609 100644 --- a/src/safe-guides/coding_practice/cargo/P.CAR.01.md +++ b/src/safe-guides/coding_practice/cargo/P.CAR.01.md @@ -6,6 +6,6 @@ 但需要注意,crate 之间的依赖关系应该是单向的,避免相互依赖的情况。 -但 Rust 中 编译时间、性能、编译大小之间,在考虑优化的时候也是需要权衡的。 +但 Rust 中编译时间、性能、编译大小之间,在考虑优化的时候也是需要权衡的。 内联是优化的关键,当编译单元越大,内联优化效果就越好。所以需要权衡 crate 划分的粒度。 diff --git a/src/safe-guides/coding_practice/cargo/P.CAR.03.md b/src/safe-guides/coding_practice/cargo/P.CAR.03.md index 581e92ef..cdcd7f8c 100644 --- a/src/safe-guides/coding_practice/cargo/P.CAR.03.md +++ b/src/safe-guides/coding_practice/cargo/P.CAR.03.md @@ -2,4 +2,4 @@ **【描述】** -考虑将条件编译 `--cfg` 使用 `cargo features` 代替,使用 Rust 原生的条件编译兼容性更好些。 +`cargo features` 为 Rust 原生的条件编译,可用于代替 `--cfg` 参数且兼容性更好。 diff --git a/src/safe-guides/coding_practice/macros/P.MAC.01.md b/src/safe-guides/coding_practice/macros/P.MAC.01.md index 3a718306..7accabe0 100644 --- a/src/safe-guides/coding_practice/macros/P.MAC.01.md +++ b/src/safe-guides/coding_practice/macros/P.MAC.01.md @@ -2,7 +2,7 @@ **【描述】** -能使用宏写出强大和用户友好的宏API的人,重点不仅是因为他们对宏如何实现掌握的好,而是因为他们同时也掌握了宏之外关于 Rust 的一切。 +当一个开发者想要能写出强大且用户友好的宏API时,不仅需要掌握如何用宏去实现,更需要掌握宏之外关于 Rust 的一切。 宏设计的重点在于宏生成什么样的代码,而不是宏如何生成代码。 diff --git a/src/safe-guides/coding_practice/macros/P.MAC.02.md b/src/safe-guides/coding_practice/macros/P.MAC.02.md index d78e04ee..6ca857d8 100644 --- a/src/safe-guides/coding_practice/macros/P.MAC.02.md +++ b/src/safe-guides/coding_practice/macros/P.MAC.02.md @@ -2,7 +2,7 @@ **【描述】** -Rust 宏可以让开发者定义自己的DSL,但是在使用宏的时候,要尽可能贴近Rust的语法。这样可以增强可读性,让其他开发者在使用宏的时候,可以猜测出它的生成的代码。 +Rust 宏可以让开发者定义自己的 DSL,但是在使用宏的时候,要尽可能贴近 Rust 的语法。这样可以增强可读性,让其他开发者在使用宏的时候,可以猜测出它生成的代码。 **【反例】** diff --git a/src/safe-guides/coding_practice/macros/decl/P.MAC.DCL.03.md b/src/safe-guides/coding_practice/macros/decl/P.MAC.DCL.03.md index e06a52ec..d8908dd6 100644 --- a/src/safe-guides/coding_practice/macros/decl/P.MAC.DCL.03.md +++ b/src/safe-guides/coding_practice/macros/decl/P.MAC.DCL.03.md @@ -2,7 +2,7 @@ **【描述】** -`macro_rules!` 定义声明宏时,非终止的元变量匹配必须紧随一个已被决定可以在这种匹配之后安全使用的标记。 +`macro_rules!` 定义声明宏时,非终止的元变量匹配必须紧随一个已被决定能在这种匹配之后安全使用的标记。 具体的规则参见:[Follow-set Ambiguity Restrictions](https://doc.rust-lang.org/reference/macros-by-example.html#follow-set-ambiguity-restrictions) diff --git a/src/safe-guides/coding_practice/macros/decl/P.MAC.DCL.05.md b/src/safe-guides/coding_practice/macros/decl/P.MAC.DCL.05.md index d7525028..b2854135 100644 --- a/src/safe-guides/coding_practice/macros/decl/P.MAC.DCL.05.md +++ b/src/safe-guides/coding_practice/macros/decl/P.MAC.DCL.05.md @@ -2,7 +2,7 @@ **【描述】** -使用宏替换(substitution)元变量,就是指把已经进行过宏解析的 token 再次传给宏,需要注意,此时传入的 token,已经被看作是宏解析器解析后的 AST 节点了。 +使用宏替换(substitution)元变量,就是指把已经进行过宏解析的 token 再次传给宏,需要注意此时传入的 token 已经被看作是宏解析器解析后的 AST 节点了。 片段分类符介绍([fragment-specifier](https://doc.rust-lang.org/nightly/reference/macros-by-example.html#metavariables)) diff --git a/src/safe-guides/coding_practice/macros/decl/P.MAC.DCL.06.md b/src/safe-guides/coding_practice/macros/decl/P.MAC.DCL.06.md index e7616b73..804105ad 100644 --- a/src/safe-guides/coding_practice/macros/decl/P.MAC.DCL.06.md +++ b/src/safe-guides/coding_practice/macros/decl/P.MAC.DCL.06.md @@ -15,7 +15,7 @@ struct Dummy(i32); impl Dummy { fn double(self) -> Dummy { - make_mutable!(self); // 这里传入的 self 和宏内部 let 定义的 self 不是一码事 + make_mutable!(self); // 这里传入的 self 和宏内部 let 定义的 self 不同 self.0 *= 2; self } diff --git a/src/safe-guides/coding_practice/macros/proc.md b/src/safe-guides/coding_practice/macros/proc.md index 4dd86941..669221fc 100644 --- a/src/safe-guides/coding_practice/macros/proc.md +++ b/src/safe-guides/coding_practice/macros/proc.md @@ -6,7 +6,7 @@ syn/quote 不仅能用于过程宏,还广泛用于代码生成(*codegen*)、静态分析等用途,例如 tonic-build/prost 源码中也用到了 syn/quote 。 -因此本过程宏规范不仅适用于过程宏,部分规范(例如 [P.MAC.Proc.06](./macros/proc/P.MAC.Proc.06.md))还适用于 prost 这种代码生成库 +因此本过程宏规范不仅适用于过程宏,部分规范(例如 [P.MAC.PRO.06](./proc/P.MAC.PRO.06.md)) 还适用于 prost 这种代码生成库 过程宏必须被单独定义在一个类型为`proc-macro` 的 crate 中。 @@ -18,9 +18,9 @@ syn/quote 不仅能用于过程宏,还广泛用于代码生成(*codegen*)、 ## 列表 -- [P.MAC.PRO.01 不要使用过程宏来规避静态分析检查](.proc/P.MAC.PRO.01.md) -- [P.MAC.PRO.02 实现过程宏时要对关键特性增加测试](.proc/P.MAC.PRO.02.md) -- [P.MAC.PRO.03 保证过程宏的卫生性](.proc/P.MAC.PRO.03.md) -- [P.MAC.PRO.04 给出正确的错误位置](.proc/P.MAC.PRO.04.md) -- [P.MAC.PRO.05 代码生成要按情况选择使用过程宏还是 build.rs](.proc/P.MAC.PRO.05.md) -- [P.MAC.PRO.06 build.rs 生成的代码要保证没有任何警告](.proc/P.MAC.PRO.06.md) \ No newline at end of file +- [P.MAC.PRO.01 不要使用过程宏来规避静态分析检查](./proc/P.MAC.PRO.01.md) +- [P.MAC.PRO.02 实现过程宏时要对关键特性增加测试](./proc/P.MAC.PRO.02.md) +- [P.MAC.PRO.03 保证过程宏的卫生性](./proc/P.MAC.PRO.03.md) +- [P.MAC.PRO.04 给出正确的错误位置](./proc/P.MAC.PRO.04.md) +- [P.MAC.PRO.05 代码生成要按情况选择使用过程宏还是 build.rs](./proc/P.MAC.PRO.05.md) +- [P.MAC.PRO.06 build.rs 生成的代码要保证没有任何警告](./proc/P.MAC.PRO.06.md) diff --git a/src/safe-guides/coding_practice/memory/lifetime/P.MEM.LFT.02.md b/src/safe-guides/coding_practice/memory/lifetime/P.MEM.LFT.02.md index 28f52023..b2f44a49 100644 --- a/src/safe-guides/coding_practice/memory/lifetime/P.MEM.LFT.02.md +++ b/src/safe-guides/coding_practice/memory/lifetime/P.MEM.LFT.02.md @@ -7,7 +7,7 @@ - Early bound。一般情况下,`'a: 'b` 以及 `impl<'a>` 这种方式是 early bound,意味着这些生命周期参数会在当前作用域单态化生命周期实例。 - Late bound。默认的 `'a` 或 `for<'a>` 是在实际调用它们的地方才单态化生命周期实例。 -在不同的场景下,需要指定合适的单态化方式,才能让编译器明白开发者的意图。 +在不同的场景下需要指定合适的单态化方式,才能让编译器明白开发者的意图。 在使用匿名生命周期 `'_` 的时候需要注意,如果有多个匿名生命周期,比如 `('_,'_)` ,每个匿名生命周期都会有自己的单独实例。 diff --git a/src/safe-guides/coding_practice/threads/lock-free/P.MTH.LKF.01.md b/src/safe-guides/coding_practice/threads/lock-free/P.MTH.LKF.01.md index 0a531dbf..a39938f0 100644 --- a/src/safe-guides/coding_practice/threads/lock-free/P.MTH.LKF.01.md +++ b/src/safe-guides/coding_practice/threads/lock-free/P.MTH.LKF.01.md @@ -2,8 +2,9 @@ **【描述】** -不要认为无锁编程性能就一定高,使用时需要注意的地方比使用同步锁都多,比如指令重排、ABA 问题、内存顺序是否指定正确等。 +无锁编程性能不一定比同步锁高。 -正确实现无锁编程比使用同步锁要困难很多。所以,除非有必要,否则直接使用同步锁就可以。 +使用无锁编程时需要注意的地方比使用同步锁多,比如指令重排、ABA 问题、内存顺序是否指定正确等。 +正确实现无锁编程比使用同步锁要困难很多。所以,除非必要,否则直接使用同步锁就可以。 也有一些 [性能测试](https://github.com/magiclen/rust-performance-measurement/blob/master/benches/atomic_mutex.rs) 作为参考,原子类型的性能比互斥锁的性能大概要好四倍左右。所以,当在同一个临界区内要有超过四次原子操作,也许使用互斥锁更加简单一些。 diff --git a/src/safe-guides/coding_practice/threads/lock-free/P.MTH.LKF.02.md b/src/safe-guides/coding_practice/threads/lock-free/P.MTH.LKF.02.md index 203c2e57..2dfecf5a 100644 --- a/src/safe-guides/coding_practice/threads/lock-free/P.MTH.LKF.02.md +++ b/src/safe-guides/coding_practice/threads/lock-free/P.MTH.LKF.02.md @@ -7,8 +7,8 @@ Rust 原子类型使用 [`C++20` 的内存顺序模型](https://zh.cppreference. 目前 Rust 引入五种内存顺序:`Relaxed / Release / Acquire / AcqRel / SeqCst`。 在无锁编程中,指定正确的内存顺序是很重要很复杂的一件事,这里有一些建议: -1. 如果你对程序中的原子类型同步方式的判断没有太多信息,建议你使用 `SeqCst`,它表示顺序一致性,会强制所有线程都同意程序指令以单一全局线性的方式来执行。这样可以保证安全性,但性能有一定损失。 -2. 如果你对无锁实现中线程间发生的数据竞争带来的后果不是特别关心,则可以放心使用 `Relaxed`,因为它性能最好。 +1. 如果对程序中的原子类型同步方式的判断没有太多信息,建议使用 `SeqCst`,它表示顺序一致性,会强制所有线程都同意程序指令以单一全局线性的方式来执行。这样可以保证安全性,但性能有一定损失。 +2. 如果对无锁实现中线程间发生的数据竞争带来的后果不是特别关心,则可以放心使用 `Relaxed`,因为它性能最好。 3. 当多个线程之间操作内存中同一个位置有因果关系时,适合使用 `Acquire / Release / AcqRel` 来配对。比如,线程 A 写 (`Release`) 内存中的一个位置,然后线程 B 随后读 (`Acquire`) 内存中一个相同的位置,就会产生一个因果关系,所以为了保证 A 的每次写入都能在 B 读取之前被观察到。如果 A 和 B 访问不同内存位置,则没有因果关系。 **【正例】**