namespaces - 在 Rust 中声明多个 "use"语句是否被认为是不好的风格?

标签 namespaces rust std using

在 Rust 中声明多个“use”语句是否被认为是不好的风格?

我是一名 C++ 程序员,最近开始尝试 Rust。我在审查 Rust 代码时注意到的一件事是,在许多 Rust 程序中,程序顶部会有一堆 use 语句。来自 C++,不鼓励使用 using namespace std 尤其是在制作头文件时,但在我见过的大多数 Rust 程序中似乎并非如此。

那么,以下哪个简单示例被认为是更好的 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)。事实上,它们在语义上有很大不同。

using namespace 在 C++ 中将命名空间的全部内容包含到当前作用域中,因此,例如,您可以使用 cout 而不是 std::输出:

using namespace std;

cout << "Hello!\n";
然而,在 Rust 中

use 仅包含指定的名称,因此您仍然需要限定您实际引用的项目:

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 仍然需要模块限定符,因此 Rust 中的 use 更像是 using C++ 中的 (没有 namespace)。因为 use 在导入的内容上非常具体,所以几乎总是使用它被认为是一种很好的风格,所以你的第一个例子是惯用的。

事实上,使用命名空间更像是 Rust 中的 glob 导入:

use std::*;

而且 glob 导入确实有点令人沮丧。然而,Rust 结构约定比 C++ 使用的约定更灵活(特别是在 std 库中),所以 use std::* 不会给你整个标准库,只有顶部级模块。全局导入在其他一些情况下也很有用,例如当从另一个模块重新导出名称或在一个模块中组装所有库扩展特征时。

不,无论您是在编写库还是可执行文件,约定都不会改变。 Rust 没有任何像 C/C++ 的带有文字包含的 header ,因此每个编译单元都是完全独立的并且可以有任何你喜欢的导入 - 它不会影响它的用户(除非这些是 pub use' s,当然)。

关于namespaces - 在 Rust 中声明多个 "use"语句是否被认为是不好的风格?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29013617/

相关文章:

android - 如何将库资源添加到 Cordova 项目?

ruby - 使用 "::"而不是 "module ..."用于 Ruby 命名空间

compiler-errors - 是否有 -Wall -Werror 的 rustc 等价物?

rust - Rust 中的 Drop 特性会修改作用域规则吗?

c++ - 如何将十六进制字符串拆分为 std::vector?

c++ - 如果从 GetProcAddress 获得的函数指针使用 stdlib,程序将崩溃

c++ - 将 vector<Class*> 复制/包装到 vector<Class>

c++ - C++ 中的命名空间和运算符重载

namespaces - scmmanager - 如何修改命名空间的名称?

pointers - 为什么 Rust 认为泄漏内存是安全的?