在Rust中声明多个"use"语句被认为是糟糕的风格吗?我是一个C++程序员,最近开始try Rust .当我回顾Rust代码时,我注意到的一件事是,在许多Rust程序中,程序顶部会有一堆use条语句.来自C++,它被禁止使用using namespace std,尤其是在头文件,但这似乎不是在大多数的 rust 蚀程序,我见过.那么以下哪一个简单的例子被认为是更好的编程风格呢?如果你在制作二进制程序和模块,它会改变吗?为什么?

use std::sync::Arc;
use std::sync::Mutex;
use std::thread::Thread;
use std::rand::random;

fn main() {
    let mut vec: Vec<char> = (0u8..10).map(|i| i as char).collect();

    let mut data = Arc::new(Mutex::new(vec));
    for i in 1usize..10 {
        let data = data.clone();
        let thread = Thread::spawn(move || {
            let mut data = match data.lock() {
                Ok(guard)   => guard,
                Err(e)      => panic!("{}, was poisoned", e)
            };
            data.push(random::<char>());
        });
    }
}

或者这个...

fn main() {
    let mut vec: Vec<char> = (0u8..10).map(|i| i as char).collect();

    let mut data = std::sync::Arc::new(
                            std::sync::Mutex::new(vec)
                                        );
    for i in 1usize..10 {
        let data = data.clone();
        let thread = std::thread::Thread::spawn(move || {
            let mut data = match data.lock() {
                Ok(guard)   => guard,
                Err(e)      => panic!("{}, was poisoned", e)
            };
            data.push(std::rand::random::<char>());
        });
    }
}

推荐答案

你可能会被相似的名字(useusing namespace)弄糊涂.事实上,它们在语义上非常不同.

C++中的using namespace包含命名空间的全部内容,因此,例如,可以使用cout而不是std::cout:

using namespace std;

cout << "Hello!\n";

但是,use in Rust仅包含指定的名称,因此您仍然必须限定您实际引用的项目:

use std::mem;
use std::fmt::Debug;

fn do_something<T: Debug>(t: T) { ... }

fn main() {
    let (mut x, mut y) = ...;
    mem::swap(&mut x, &mut y);
}

注意Debug如何使用没有限定符,但是swap仍然需要模块限定符,所以在C++中,use的Rust 更像using(没有namespace).因为use在导入内容上非常具体,所以几乎总是使用它被认为是一种好的样式,所以您的第一个示例就是惯用的一个.

事实上,using namespace更像是 rust 迹斑斑的glob进口产品:

use std::*;

而全球进口确实有点不受欢迎.然而,Rust struct 约定更灵活,使用的C++(特别是在STD库),所以use std::*不会给你整个标准库,只有顶层模块.Glob导入在其他几种情况下也很有用,例如,当从另一个模块重新导出名称或在一个模块中组装所有库扩展特性时.

不,无论您是在编写库还是在编写可执行文件,约定都不会改变.Rust没有任何类似于C/C++的包含文字的头文件,因此每个编译单元都是完全独立的,可以有任何你喜欢的导入——它不会影响用户(当然,除非是pub use个).

Rust相关问答推荐

如何定义使用拥有的字符串并返回拥有的Split的Rust函数?

无需通过ASIO输入音频,并使用cpal进行反馈示例

为什么迭代器上的`. map(...)`的返回类型如此复杂?

在rust中如何修改一个盒装函数并将其赋回?

如果成员都实现特征,是否在多态集合上实现部分重叠的特征?

铁 rust 中的泛型:不能将`<;T作为添加>;::Output`除以`{Float}`

Rust编译器似乎被结果类型与anyhow混淆

什么时候使用FuturesOrdered?

为什么比较Option<;字符串>;具有常数Option<&;str>;需要显式类型转换吗?

具有多个键的 HashMap

Rust:为什么 Pin 必须持有指针?

实现泛型的 Trait 方法中的文字

为什么传递 option.as_ref 的行为不同于使用匹配块并将内部映射到 ref 自己?

Rust 中函数的类型同义词

改变不实现克隆的 dioxus UseState struct

通用函数中的生命周期扣除和borrow (通用测试需要)

为实现特征的所有类型实现显示

Rust 跨同一文件夹中文件的可见性

TinyVec 如何与 Vec 大小相同?

为移动和借位的所有组合实现 Add、Sub、Mul、Div