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关键字引入后,一样可直接编译使用了。

posted @ 2023-10-23 13:12  00lab  阅读(11)  评论(0编辑  收藏  举报