Skip to content

Commit c395cac

Browse files
authored
同步4.14 模块章节 (#66)
* update module * Update G.MOD.01 使用导入模块中的类型或函数,在某些情况下需要带模块名前缀.md * Update G.MOD.02 如果是作为库供别人使用,在lib.rs中重新导出对外类型、函数和trait等.md * Update P.MOD.01 合理控制对外接口和模块之间的可见性.md * Update P.MOD.02 将模块的测试移动到单独的文件。有助于增加编译速度.md
1 parent c6c624d commit c395cac

7 files changed

+234
-0
lines changed
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
## P.MOD.01 使用导入模块中的类型或函数,在某些情况下需要带 模块名前缀
2+
3+
**【描述】**
4+
5+
对于标准库中,很多人都熟知的类型 ,比如 `Arc`/ `Rc`/ `Cell`/ `HashMap` 等 , 可以导入它们直接使用。
6+
7+
但是对于可能引起困惑的函数,比如 `std::ptr::replace``std::mem::replace` ,在使用它们的时候,就必须得带上模块前缀。
8+
9+
使用一些第三方库中定义的类型或函数,也建议带上crate或模块前缀。如果太长的话,可以考虑使用 `as``type` 来定义别名。
10+
11+
以上考虑都是为了增强代码的可读性、可维护性。
12+
13+
**【正例】**
14+
15+
```rust
16+
use std::sync::Arc;
17+
let foo = Arc::new(vec![1.0, 2.0, 3.0]); // 直接使用 Arc
18+
let a = foo.clone();
19+
20+
// 需要带上 ptr 前缀
21+
use std::ptr;
22+
let mut rust = vec!['b', 'u', 's', 't'];
23+
// `mem::replace` would have the same effect without requiring the unsafe
24+
// block.
25+
let b = unsafe {
26+
ptr::replace(&mut rust[0], 'r')
27+
};
28+
```
29+
30+
**【Lint 检测】**
31+
32+
| lint name | Clippy 可检测 | Rustc 可检测 | Lint Group | 是否可定制 |
33+
| --------- | ------------- | ------------ | ---------- | ---------- |
34+
| _ | no | no | _ | yes |
35+
36+
【定制化参考】
37+
38+
可以检测外部模块导入的自定义的类型是否带模块前缀,给予建议。
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
## G.MOD.02 如果是作为库供别人使用,在 `lib.rs`中重新导出对外类型、函数和 trait 等
2+
3+
**【级别】** 建议
4+
5+
**【描述】**
6+
7+
这样使用方在使用的时候,就不需要`use crate::mod::mod::struct`,可以直接使用`use crate::struct`,好处是使用方`use`的时候会比较方便和直观。
8+
9+
**【正例】**
10+
11+
```rust
12+
// From syn crate
13+
pub use crate::data::{
14+
Field, Fields, FieldsNamed, FieldsUnnamed, Variant, VisCrate, VisPublic, VisRestricted,
15+
Visibility,
16+
};
17+
```
18+
19+
**【Lint 检测】**
20+
21+
| lint name | Clippy 可检测 | Rustc 可检测 | Lint Group | 是否可定制 |
22+
| --------- | ------------- | ------------ | ---------- | ---------- |
23+
| _ | no | no | _ | yes |
24+
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
2+
## G.MOD.03 导入模块不要随便使用 通配符`*`
3+
4+
**【级别】** 建议
5+
6+
**【描述】**
7+
8+
使用通配符导入会污染命名空间,比如导入相同命名的函数或类型。
9+
10+
**【反例】**
11+
12+
```rust
13+
14+
use crate2::*; // Has a function named foo
15+
foo(); // Calls crate1::foo
16+
```
17+
18+
**【正例】**
19+
20+
```rust
21+
use crate1::foo; // Imports a function named foo
22+
foo(); // Calls crate1::foo
23+
```
24+
25+
**【例外】**
26+
27+
```rust
28+
use prelude::*;
29+
30+
#[test]
31+
use super::*
32+
```
33+
34+
**Lint 检测】**
35+
36+
| lint name | Clippy 可检测 | Rustc 可检测 | Lint Group | level |
37+
| ------------------------------------------------------------ | ------------- | ------------ | ---------- | ----- |
38+
| [wildcard_imports](https://rust-lang.github.io/rust-clippy/master/#wildcard_imports) | yes | no | pedantic | allow |
39+
40+
该 lint 可以通过 clippy 配置项 `warn-on-all-wildcard-imports = false` 来配置,用于是否禁用 `prelude`/ `super` (测试模块中) 使用通配符导入, 默认是 `false`。
Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
## G.MOD.04 一个项目中应该避免使用不同的模块布局风格
2+
3+
**【级别】** 建议
4+
5+
**【描述】**
6+
7+
Rust 支持两种 模块布局,文件夹内使用 `mod.rs` 或者是使用跟文件夹同名的文件名,来组织模块。
8+
9+
但是项目里如果混合这两种模块布局,是比较让人困惑的,最好统一为同一种风格。
10+
11+
上面两种 lint ,选择其中一种用于检查是否存在不同的模块布局。
12+
13+
**【反例】**
14+
15+
```rust
16+
// 使用 `self_named_module_files`,不允许下面模块布局
17+
src/
18+
stuff/
19+
stuff_files.rs
20+
stuff.rs
21+
lib.rs
22+
23+
// 使用 `mod_module_files`,不允许下面模块布局
24+
25+
src/
26+
stuff/
27+
stuff_files.rs
28+
mod.rs
29+
lib.rs
30+
```
31+
32+
**【正例】**
33+
34+
```rust
35+
// 使用 `self_named_module_files`,允许下面模块布局
36+
src/
37+
stuff/
38+
stuff_files.rs
39+
mod.rs
40+
lib.rs
41+
42+
// 使用 `mod_module_files`,允许下面模块布局
43+
src/
44+
stuff/
45+
stuff_files.rs
46+
stuff.rs
47+
lib.rs
48+
```
49+
50+
**【Lint 检测】**
51+
52+
| lint name | Clippy 可检测 | Rustc 可检测 | Lint Group | level |
53+
| ------------------------------------------------------------ | ------------- | ------------ | ----------- | ----- |
54+
| [self_named_module_files](https://rust-lang.github.io/rust-clippy/master/#self_named_module_files) | yes | no | restriction | allow |
55+
| [mod_module_files](https://rust-lang.github.io/rust-clippy/master/#mod_module_files) | yes | no | restriction | allow |
56+
57+
58+
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
## G.MOD.05 不要在私有模块中 设置其内部类型或函数方法 为 `pub(crate)`
2+
3+
**【级别】** 建议
4+
5+
**【描述】**
6+
7+
如果在私有模块中设置 `pub(crate)` 可能会让使用者产生误解。建议用 `pub` 代替。
8+
9+
**【反例】**
10+
11+
```rust
12+
mod internal {
13+
pub(crate) fn internal_fn() { }
14+
}
15+
```
16+
17+
**【正例】**
18+
19+
```rust
20+
mod internal {
21+
pub fn internal_fn() { }
22+
}
23+
```
24+
25+
**【Lint 检测】**
26+
27+
| lint name | Clippy 可检测 | Rustc 可检测 | Lint Group | level |
28+
| ------------------------------------------------------------ | ------------- | ------------ | ---------- | ----- |
29+
| [redundant_pub_crate](https://rust-lang.github.io/rust-clippy/master/#redundant_pub_crate) | yes | no | nursery | allow |
30+
31+
注意:此 lint 为 nursery,意味着有 Bug。
32+
33+
34+
35+
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
## P.MOD.01 合理控制对外接口和模块之间的可见性
2+
3+
**【描述】**
4+
5+
Rust提供强大的模块(module)系统,并且可以管理这些模块之间的可见性(公有(public)或私有(private))。
6+
7+
1、对于提供给其他crate使用的对外函数、结构体、trait等类型需要严格控制对外pub的范围,避免将内部成员对外提供。
8+
9+
2、对于crate内部,mod之间可见的类型,需要添加上`pub(crate) `
10+
11+
3、对于mod内部私有的类型,不要添加`pub(crate) `或者`pub`
12+
13+
**【正例】**
14+
15+
```rust
16+
// lib.rs
17+
pub mod sha512;
18+
pub use sha512::Sha512;
19+
20+
// sha512.rs
21+
pub struct Sha512 {
22+
inner: Sha512Inner, // inner作为内部结构体,不添加pub描述
23+
}
24+
25+
```
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
## P.MOD.02 将模块的测试移动到单独的文件,有助于增加编译速度
2+
3+
**【描述】**
4+
5+
将模块的测试代码 移到一个单独的文件中,并且用 `#[cfg(test)] 来条件编译 tests 的mod,这样可以减少rebuild和编译时间,在大型项目中很重要。
6+
7+
**【正例】**
8+
9+
```rust
10+
src/
11+
|--codes.rs
12+
|--codes/test.rs
13+
```
14+

0 commit comments

Comments
 (0)