Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

14.3 使用 pub use 导出方便使用的 API

14.3.1 使用 pub use 重导出 API

第七章中我们介绍了 mod 关键字,我们使用它来将代码组织为模块。其中介绍的 pub 关键字可以将模块或方法设置为公共的,以便外部代码调用。而外部代码要将模块或方法引入当前作用域,就得使用 use 关键字。

使用这些关键字就可将代码组织为面向开发者友好的形式。但是这种结构对代码库的最终用户不一定特别友好。比如说,crate 的结构在开发时对于开发者很友好,但是对于使用者不够方便。开发者会把程序结构分为很多层,使用者想要找到这种深层结构中的某个类型就很费劲。比如说:my_crate::some_module::another_module::UsefulType,而比较好用的写法是 my_crate::UsefulType

对于这种问题,不需要重新组织内部代码结构,使用 pub use 就可以重导出条目,创建一个与内部私有结构不同的对外公共结构。重导出这个操作会取得某个位置上的公共条目,并将其公开到另外一个位置,就好像它就定义在这个新的位置上。

看个例子: lib.rs:

#![allow(unused)]
fn main() {
//! # Art
//!
//! A library for modeling artistic concepts.

pub mod kinds {
    /// The primary colors according to the RYB color model.
    pub enum PrimaryColor {
        Red,
        Yellow,
        Blue,
    }

    /// The secondary colors according to the RYB color model.
    pub enum SecondaryColor {
        Orange,
        Green,
        Purple,
    }
}

pub mod utils {
    use crate::kinds::*;

    /// Combines two primary colors in equal amounts to create
    /// a secondary color.
    pub fn mix(c1: PrimaryColor, c2: PrimaryColor) -> SecondaryColor {
        //...
    }
}
}
  • kinds 这个模块下有两个枚举类型,PrimaryColorSecondaryColor,用于存储颜色变体。
  • utils 模块下有一个叫 mix 的函数,这个函数的功能就是把两个 PrimaryColor 值混合成为 SecondaryColor。这里没有放出其中的代码。
  • 把枚举类型放在 kinds 下,把函数放在 utils 下,对于开发者来说非常友好。

main.rs:

use art::kinds::PrimaryColor;
use art::utils::mix;

fn main() {
    let red = PrimaryColor::Red;
    let yellow = PrimaryColor::Yellow;
    mix(red, yellow);
}

这里用到了 lib.rs 中的枚举类型和 mix 函数。为了引入作用域写了三层,而且枚举类型和函数在不同的模块中,对于使用者来说非常麻烦。

此时生成的 crate 文档长这样: art crate 的 rustdoc 文档页,列出 kinds 与 utils 模块

如果我们使用重导出来重构代码: lib.rs:

#![allow(unused)]
fn main() {
//! # Art
//!
//! A library for modeling artistic concepts.

pub use self::kinds::PrimaryColor;
pub use self::kinds::SecondaryColor;
pub use self::utils::mix;

pub mod kinds {
    /// The primary colors according to the RYB color model.
    pub enum PrimaryColor {
        Red,
        Yellow,
        Blue,
    }

    /// The secondary colors according to the RYB color model.
    pub enum SecondaryColor {
        Orange,
        Green,
        Purple,
    }
}

pub mod utils {
    use crate::kinds::*;

    /// Combines two primary colors in equal amounts to create
    /// a secondary color.
    pub fn mix(c1: PrimaryColor, c2: PrimaryColor) -> SecondaryColor {
        //...
    }
}
}

main.rs:

use art::mix; 
use art::PrimaryColor;

fn main() {
    let red = PrimaryColor::Red;
    let yellow = PrimaryColor::Yellow;
    mix(red, yellow);
}

这个时候调用枚举类型和函数就不需要一层层地写模块路径了。

此时生成的 crate 文档: art crate 的 rustdoc 文档页,显示 PrimaryColor、SecondaryColor 与 mix 的 Re-exports 文档中出现了 Re-exports 部分,所有重新导出的条目都写在了这里。对于 crate 的实际使用者来说,查找这些类型和函数就非常方便了。