Rust"use"与C++"using namespace"

Dan*_*son 8 namespaces using std rust

在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>());
        });
    }
}
Run Code Online (Sandbox Code Playgroud)

或这个...

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>());
        });
    }
}
Run Code Online (Sandbox Code Playgroud)

Vla*_*eev 17

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

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

using namespace std;

cout << "Hello!\n";
Run Code Online (Sandbox Code Playgroud)

use 但是,在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);
}
Run Code Online (Sandbox Code Playgroud)

注意如何Debug在没有限定符的情况下使用但swap仍需要模块限定符,因此use在Rust中更像是using(没有namespace)在C++中.因为use它导入的内容非常具体,所以它几乎总是被认为是一种很好的风格,所以你的第一个例子是惯用的.

事实上,using namespace更像是Rust中的glob导入:

use std::*;
Run Code Online (Sandbox Code Playgroud)

而且确实有些气馁.但是,Rust结构化约定比C++使用的更加灵活(特别是在std库中),所以use std::*不会给你整个标准库,只提供顶级模块.Glob导入在其他几种情况下也很有用,例如,当从另一个模块重新扩展名称或在一个模块中组装所有库扩展特征时.

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

  • 请注意,C++也有单个名称`using`,例如`using std :: cout;`在C++中工作得很好.所以不,`using`不是一个glob import语句.另一方面,"使用命名空间"是,它的效果非常明显. (7认同)