41_cargo发布前准备

前言

学习如何发布包,会分成几篇介绍,

  1. 通过release profile来自定义构建
  2. crates.io/ 上发布库
  3. 通过workspaces组织大工程
  4. 安装库
  5. 使用自定义命令扩展cargo

本篇主要讲第一个通过release profile来自定义构建,内容有构建、文档注释、pubuse

1. 通过release profile来自定义构建

  • release profile是发布配置:
    • 是预定义的
    • 也是可定义的,可使用不同的配置,对编译代码拥有更多的控制
  • 每个profile的配置都独立于其他的profile。
  • 在cargo里主要有两种profile
    • dev profile:适用于开发,cargo build
    • release profile:适用于发布,cargo build --release

我们在编译的时候,如果执行的是cargo build命令,那么将使用dev profile;如果使用cargo build --release命令,将使用release profile。

2. 自定义profile

  • 针对每个profile,cargo都提供了默认的配置,
  • 如果想自定义某个xxx profie:
    • 可以在Cargo.toml里添加[profile.xxx]区域,在里面覆盖默认的子集。 通常我们不会覆盖所有的配置,只需要覆盖想修改的配置即可。

如果我们想针对devrelease的 profle进行修改,

Cargo.toml文件示例内容如下

ini 复制代码
[package]
name = "s43_minigrep_optmize"
version = "0.1.0"
edition = "2021"

# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html

[dependencies]

[profile.dev]
opt-level = 0

[profile.release]
opt-level = 3

opt-level参数决定是否对编译进行优化,会影响编译时间。

  • dev profile的默认值是0,编译没有优化,这样编译速度更快,但编译产物效率较低;
  • release profile的默认值是3,这样编译时间更长,但是得到的产物运行效率更高。

命令行输出产生:

对于每个配置的默认值和完整选项,可以参考doc.rust-lang.org/stable/carg...

3. 发布crate到crate.io

之前我们通过crates.io下载了第三方库,我们也可以通过crates.io发布包来共享我们的代码。crate的注册表在crates.io,它会分发已注册的包的源代码,主要托管开源的代码。类似npm。

4. 文档注释

4.1 生成文档注释

rust使用一种特殊的文档注释,

  • 用于生成文档,
    • 生成项目的HTML文档
    • 显示公共API的文档注释,表明如何使用API
    • 使用///
    • 文档中支持Markdown语法
    • 放在被放在被说明条目之前

案例:

写一个lib.rs

rust 复制代码
/// Add one to the number given
///
/// # Examples
///
/// ```
/// let arg = 5;
/// let answer = hello_api::add_one(arg);
///
/// assert_eq!(6, answer);
/// ```

pub fn add_one(x: i32) -> i32 {
    x + 1
}
  • 使用cargo doc生成html文档,

    • 它会运行rustdoc工具,该工具在安装rust的时候就自带了。
    • 生成的html文档放在target/doc目录下。
  • cargo doc --open命令

    • 构建当前crate的文档,(也包含crate依赖项文档)
    • 在浏览器打开文档

crates:

具体函数使用

4.2 常用章节

在文档注释中,会经常使用一些章节标注,常用章节如下

Example: 示例代码 panics: 函数可能发生panic的场景 Errors: 如果函数返回Result,描述可能的错误种类,以及可导致错误的条件 Safety: 如果函数处于unsafe调用,就应该解释函数unsafe的原因,以及调用者应当确保使用的前提

4.3 文档注释作为测试

实际上,运行cargo test时,会把文档注释中的示例代码作为测试来运行,如下是的示例代码

rust 复制代码
/// Adds one to the number given.
/// 
/// # Examples
///
/// ```
/// let args = 5;
/// let answer = my_crate::add_one(args);
/// 
/// assert_eq!(6, anwser);
/// ```dotnetcli
pub fn add_one(x: i32) -> i32 {
    x + 1
}

运行cargo test之后,文档注释中的示例测试代码将会被执行。

4.4 为包含注释的项添加文档注释

  • 符号: //!
  • 这类注释通常用于描述crate和模块
    • 如一个crate root(通常是src/lib.rs)
    • 在一个模块内,将crate 或模块作为整体进行记录

如下的示例代码

rust 复制代码
//! # hello_api
//!
//! `hello_api` is a collection of utilities to make performing certain calculations more convenient

/// Adds one to the number given.
/// 
/// # Examples
///
/// ```
/// let args = 5;
/// let answer = my_crate::add_one(args);
/// 
/// assert_eq!(6, anwser);
/// ```dotnetcli
pub fn add_one(x: i32) -> i32 {
    x + 1
}

使用cargo doc --open显示结果如下:

5. pub use

使用use可以到处方便使用的公共API.

问题:crate的程序结构在开发时对开发者很合理,但对于它的使用很不方便。

  • 开发者通常会把程序结构分为很多层,使用者想找到这种深层结构中的某个类型很费劲。

如下的示例:

  • 麻烦:my_crate::some_module::another_module::UsefulType;
  • 方便:my_crate::UsefulType;

上面的示例中存在多个层级,使用者很不方便对于用户来说,应该使用方便的方式。

解决方法:

  • 不希望重新组织内部的代码结构
  • 使用pub use,可以重新导出,创建与内部私有结构不同的对外公共结构。

下面我们看个示例,先创建src/lib.rs文件,写入如下的内容:

rust 复制代码
//! # Art
//! 
//! A library for modeling artistic concept.

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

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

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

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

然后在src/main.rs调用,如下代码

rust 复制代码
use hello_pubuse::kinds::PrimaryColor;
use hello_pubuse::utils::mix;

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

使用 cargo doc --open生成文档,是嵌入式的。

可以看到我们在引入函数的时候,层级结构比较深。我们下面做一个优化,使用pub use关键字在src/lib.rs里重新导出需要使用的内容到顶层结构,如下示例

rust 复制代码
//! # Art
//! 
//! A library for modeling artistic concept.

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

这时候我们使用cargo doc --open生成并查看文档,这时候文档已经表明了导出的部分,如下图

这对于crate的用户来说,查找对应的类型和函数就非常方便了。这时候我们在使用的地方直接简化导入的层级,如下示例代码

rust 复制代码
// use hello_pubuse::kinds::PrimaryColor;
// use hello_pubuse::utils::mix;
use hello_pubuse::PrimaryColor;
use hello_pubuse::mix;

正常运行。

相关推荐
无双_Joney15 分钟前
[更新迭代 - 1] Nestjs 在24年底更新了啥?(功能篇)
前端·后端·nestjs
在云端易逍遥17 分钟前
前端必学的 CSS Grid 布局体系
前端·css
ccnocare18 分钟前
选择文件夹路径
前端
艾小码18 分钟前
还在被超长列表卡到崩溃?3招搞定虚拟滚动,性能直接起飞!
前端·javascript·react.js
闰五月19 分钟前
JavaScript作用域与作用域链详解
前端·面试
泉城老铁23 分钟前
idea 优化卡顿
前端·后端·敏捷开发
前端康师傅23 分钟前
JavaScript 作用域常见问题及解决方案
前端·javascript
司宸24 分钟前
Prompt结构化输出:从入门到精通的系统指南
前端
我是日安25 分钟前
从零到一打造 Vue3 响应式系统 Day 9 - Effect:调度器实现与应用
前端·vue.js