使用 use 将两个同名类型引入同一作用域这个问题还有另一个解决办法:在这个类型的路径后面,我们使用 as 指定一个新的本地名称或者别名。

use std::io::Result as IoResult;
fn function1() -> Result {
// --snip--
# Ok(())
}
fn function2() -> IoResult<()> {
// --snip--
# Ok(())
}

使用 pub use 重导出名称
使用 use 关键字,将某个名称导入当前作用域后,这个名称在此作用域中就可以使用了,但它对此作用域之外还是私有的。如果想让其他人调用我们的代码时,也能够正常使用这个名称,就好像它本来就在当前作用域一样,那我们可以将 pub 和 use 合起来使用。这种技术被称为 ” 重导出(re−exporting)”:我们不仅将一个名称导入了当前作用域,还允许别人把它导入他们自己的作用域。

pub mod hosting {
pub fn add_to_waitlist() {}
}
}
pub use crate::front_of_house::hosting;
pub fn eat_at_restaurant() {
hosting::add_to_waitlist();
hosting::add_to_waitlist();
hosting::add_to_waitlist();
}

通过 pub use,外部代码现在可以通过新路径 hosting::add_to_waitlist 来调用 add_to_waitlist 函数。
如果没有指定 pub use,eat_at_restaurant 函数可以在其作用域中调用 hosting::add_to_waitlist,但外部代码则不允许使用这个新路径。
当你代码的内部结构与调用你代码的程序员所想象的结构不同时,重导出会很有用。例如,在这个餐馆的比喻中,经营餐馆的人会想到” 前台” 和” 后台”。但顾客在光顾一家餐馆时,可能不会以这些术语来考虑餐馆的各个部分。使用 pub use,我们可以使用一种结构编写代码,却将不同的结构形式暴露出来。
这样做使我们的库井井有条,也使开发这个库的程序员和调用这个库的程序员都更加方便。
使用外部包
在第二章中我们编写了一个猜猜看游戏。那个项目使用了一个外部包,rand,来生成随机数。为了在项目中使用 rand,在 Cargo.toml 中加入了如下行:

在 Cargo.toml 中加入 rand 依赖告诉了 Cargo 要从 crates.io 下载 rand 和其依赖,并使其可在项目代码中使用。
接着,为了将 rand 定义引入项目包的作用域,我们加入一行 use 起始的包名,它以 rand 包名开头并列出了需要引入作用域的项。回忆一下第二章的 ” 生成一个随机数” 部分,我们曾将 Rng trait 引入作用域并调用了 rand::thread_rng 函数:

use rand::Rng;
fn main() {
# println!("Guess the number!");
#
let secret_number = rand::thread_rng().gen_range(1..101);
#
# println!("The secret number is: {}", secret_number);
#
# println!("Please input your guess.");
#
# let mut guess = String::new();
#
# io::stdin()
# .read_line(&mut guess)
# .expect("Failed to read line");
#
# println!("You guessed: {}", guess);
}

crates.io 上有很多 Rust 社区成员发布的包,将其引入你自己的项目都需要一道相同的步骤:在Cargo.toml 列出它们并通过 use 将其中定义的项引入项目包的作用域中。
注意标准库(std)对于你的包来说也是外部 crate。因为标准库随 Rust 语言一同分发,无需修改Cargo.toml 来引入 std,不过需要通过 use 将标准库中定义的项引入项目包的作用域中来引用它们,比如我们使用的 HashMap:

这是一个以标准库 crate 名 std 开头的绝对路径。

Logo

开放原子开发者工作坊旨在鼓励更多人参与开源活动,与志同道合的开发者们相互交流开发经验、分享开发心得、获取前沿技术趋势。工作坊有多种形式的开发者活动,如meetup、训练营等,主打技术交流,干货满满,真诚地邀请各位开发者共同参与!

更多推荐