G.MOD.01 导入模块中的类型或函数时,应避免直接使用通配符
【级别】 建议
【描述】
使用通配符导入会污染命名空间,比如导入相同命名的函数或类型。为了避免这种情况,使用导入的类 型或函数时需要带模块名前缀。有个例外,当一个 crate 提供了 prelude 时,可以用 prelude::*
。
对于标准库中,很多人都熟知的类型 ,比如 Arc/ Rc/ Cell/ HashMap
等 , 可以导入它们直接使用。
但是对于可能引起困惑的函数,比如 std::ptr::replace
和 std::mem::replace
,在使用它们的时 候,就必须得带上模块前缀。
使用一些第三方库中定义的类型或函数,也建议带上 crate 或模块前缀。如果太长的话,可以考虑使用 as
或 type
来定义别名。
以上考虑都是为了增强代码的可读性、可维护性。
【反例】
Rust
use std::sync::Arc;
use std::ptr::*;
fn main() {
let foo = Arc::new(vec![1.0, 2.0, 3.0]); // 直接使用 Arc let a = foo.clone();
let mut rust = vec!['b', 'u', 's', 't'];
let b = unsafe {
// 不符合
// 不知道 `replace` 是来自 `std::ptr` 还是 `std::mem` 模块
replace(&mut rust[0], 'r')
};
}
【正例】
Rust
use std::sync::Arc;
use std::ptr;
fn main() {
let foo = Arc::new(vec![1.0, 2.0, 3.0];
let a = foo.clone();
let mut rust = vec!['b', 'u', 's', 't'];
let b = unsafe {
// 符合
// 需要带上 ptr 前缀,因为 `std::mem::replace` 也有同样的效果
ptr::replace(&mut rust[0]
};
}