14_rust的use关键字、拆分模块
use关键字
可用use关键字将 路径导入到作用域内,导入的内容仍然遵循私有性原则。可使用相对路径和绝对路径的方式。
mod modu1 {
pub mod modu2 {
pub fn test_func1() {}
fn test_private() {}
}
}
use crate::modu1::modu2; // 使用use关键字引入modu2模块,绝对路径的方式
use modu1::modu2; // 相对路径的方式引入
pub fn test_func2() {
modu2::test_func1(); // 通过模块名调用模块内函数
modu2::test_private(); // 编译报错:试图调私有函数
}
/*********************************/
// 也可直接引用到函数,但不易区分是本模块内的函数还是外部函数
use crate::modu1::modu2::test_func1;
pub fn test_func2() {
test_func1(); // 调用时可直接调用,但看不出来是不是模块外的
}
通常函数引用时,只引用到函数的上一级模块名,通过模块名调用函数,能直接看出是外部提供的函数。
use的习惯用法
- 函数:将函数的父级模块引入作用域(指定到父级)
- struct、enum、其它:指定完整路径(指定到本身)
use std::collections::HashMap; // 引入HashMap结构体
fn main() {
let mut map = HashMap::new();
map.insert(1, 2);
}
- 同名条目:指定到父级,到本身会引起二义性。
use std::fmt;
use std::io;
fn f1() -> fmt::Result {}
fn f2() -> io::Result {}
as关键字
as关键字可引入路径指定本地的别名
use std::fmt::Result;
use std::io::Result as IoResult;
fn f1() -> Result {}
fn f2() -> IoResult {}
使用pub use重新导出名称
使用use将路径(名称)导入到作用域后,该名称在此作用域内是私有的。
pub use: 重导出
- 将条目引入作用域
- 该条目可被外部代码引入到自己的作用域内
pub use std::io::Result as IoResult;
使用外部包(package)
1)Cargo.toml文件内添加依赖的包(package),在build的时候会从https://crates.io/里下载包。
2)use关键字将特定条目引入作用域。
如:在Cargo.toml里添加rand包
[dependencies]
rand = "0.5.5"
执行cargo build,如果报错“Blocking waiting for file lock on package cache”,
可执行“where cargo”命令获取当前cargo路径,如“C:\Users\test.cargo\bin\cargo.exe”,
进入到C:\Users\test.cargo文件夹,可看到一个叫“.package-cache”的隐藏文件,
删除“.package-cache”后重新build即可。
如果下载很慢,可切换至国内镜像,参考 https://www.cnblogs.com/UFO-blogs/p/17752286.html
在代码中使用rand库即可:
use rand::Rng;
标准库(std)的引入
标准库也被当做外部包,不过已内置在rust语言中作为语言的最基本的库,不需要修改Cargo.toml来包含std,
不过需要使用use将std中的特定条目引入当前作用域。
使用嵌套路径清理大量的use语句:
如果使用同一个包或模块下的多个条目,就会有很多行,且相同的前缀包名。
对这种情况,可使用嵌套路径在同一行内将上述多个条目进行引入,语法:
- 路径相同的部分::{路径差异的部分}
如:
use std::{cmp::Ordering, io}; // 引入多个库的情况
use std::io::{self, Write}; // 引入io本身和io下的Write模块
使用通配符(*)号将路径中所有的公共条目都引入到作用域,谨慎使用,一般使用的场景是测试场景,用于将所有测试代码引入到tests模块中。有时被用于预导入(prelude)模块。
use std::collections::*;
将模块拆分为不同文件
将模块的内容移动到其它文件:模块定义是,若模块名后是“;”,而不是代码块,rust会从模块同名的文件中加载内容,模块树的结构不会变化。随着模块逐渐变大,该技术可把模块的内容移动到其他文件中便于维护。
如对如下模块定义进行改造:
mod modu1 {
pub mod modu2 {
pub fn test_func1() {}
fn test_private() {}
}
}
在src/main.rs中只写:
mod modu1; // 不再跟随{}定义模块
创建src/modu1.rs文件,内容:
pub mod modu2;
创建文件夹src/modu1,这样与模块定义层级一致,然后创建文件src/modu1/modu2.rs,内容:
pub fn test_func1() {}
然后使用use关键字引入后,一样可直接编译使用了。