use声明语句

参考资料: https://doc.rust-lang.org/reference/items/use-declarations.html

1
2
3
4
5
6
7
8
Syntax:
UseDeclaration :
use UseTree ;

UseTree :
(SimplePath? ::)? *
| (SimplePath? ::)? { (UseTree ( , UseTree )* ,?)? }
| SimplePath ( as ( IDENTIFIER | _ ) )?

use语句最常用的做法是引用一个module item. 这些声明语句可以出现在modulesblocks中, 但最常见的是在文件的顶级结构下.

1. use语句的简写使用:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
// 导入同一个前缀下的所有paths
use a::b::{c, d, e::f, g::h::i};

// 导入同一个前缀下所有paths, 且包含该parent module本身
use a::b::{self, c, d::e};

// 也可以取别名
use a::b::{self as ab, c as abc};

// 可以用通配符导入所有path
use a::b::*;

// 还可以嵌套使用上述规则
use a::b::{self as ab, c, d::{*, e::f}}

一个例子:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
use std::collections::hash_map::{self, HashMap};

fn foo<T>(_: T){}
fn bar(map1: HashMap<String, usize>, map2: hash_map::HashMap<String, usize>){}

fn main() {
// use declarations can also exist inside of functions
use std::option::Option::{Some, None};

// Equivalent to 'foo(vec![std::option::Option::Some(1.0f64),
// std::option::Option::None]);'
foo(vec![Some(1.0f64), None]);

// Both `hash_map` and `HashMap` are in scope.
let map1 = HashMap::new();
let map2 = hash_map::HashMap::new();
bar(map1, map2);
}

2. Visibility

use语句可以被pub限定符修饰, 使用pub修饰的use语句, 可以起到’命名空间重定向’的作用, 原本在一个地方定义的name, 在被pub use之后, 其被暴露在一个新的环境中. 就类似python的import, 也会引起命名空间重定向.

注意不能引起循环引用, 总体来说和python的设计思想类似

一个re-exporting的例子:

1
2
3
4
5
6
7
8
9
10
11
12
mod quux {
pub use self::foo::{bar, baz};
pub mod foo {
pub fn bar() {}
pub fn baz() {}
}
}

fn main() {
quux::bar();
quux::baz();
}

3. Paths

这里给出的是例子

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
#![allow(unused_imports)]
use std::path::{self, Path, PathBuf}; // good: std is a crate name
use crate::foo::baz::foobaz; // good: foo is at the `root` of the crate

mod foo {

pub mod example {
pub mod iter {}
}

use crate::foo::example::iter; // good: foo is at crate root
// use example::iter; // bad in 2015 edition: relative paths are not allowed without `self`; good in 2018 edition
use self::baz::foobaz; // good: self refers to module 'foo'
use crate::foo::bar::foobar; // good: foo is at crate root

pub mod bar {
pub fn foobar() { }
}

pub mod baz {
use super::bar::foobar; // good: super refers to module 'foo'
pub fn foobaz() { }
}
}

fn main() {}

在2018版之后, 如果同一命名空间下与标准库有名字冲突的, 可以加上::来避免歧义:

1
2
3
4
5
6
use ::std::fs;  // Imports from the `std` crate, not the module below.
use self::std::fs as self_fs; // Imports the module below.

mod std {
pub mod fs {}
}

4. Underscore Imports

use path as _

使用下划线, 可以将引入的name隐藏, 当导入的是一个trait时, 当前命名空间中所有(在use path as _之后)的struct都能使用Zoo这个trait的方法(事实上, 那个Zoo struct命名为A B C D 都无所谓, 它都能访问zoo这个函数)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
mod foo {
pub trait Zoo {
fn zoo(&self) {}
}

impl<T> Zoo for T {}
}

use self::foo::Zoo as _;
struct Zoo; // Underscore import avoids name conflict with this item.

fn main() {
let z = Zoo;
z.zoo();


use声明语句
https://www.torch-fan.site/2022/07/21/use声明语句/
作者
Torch-Fan
发布于
2022年7月21日
更新于
2022年11月15日
许可协议