Loading [MathJax]/jax/output/CommonHTML/config.js
前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >RustChinaConf 2022 大会议题回顾 | Part I : Rustdoc 你可以用它做什么以及它的未来

RustChinaConf 2022 大会议题回顾 | Part I : Rustdoc 你可以用它做什么以及它的未来

作者头像
张汉东
发布于 2022-12-08 13:01:59
发布于 2022-12-08 13:01:59
61600
代码可运行
举报
文章被收录于专栏:Rust 编程Rust 编程
运行总次数:0
代码可运行

引言

这个系列是对 RustChinaConf 2022 线上大会议题的回顾,后面等官方 RustConf 2022 的视频出来也会有相关回顾文章。

本次大会分为一个主会场和七个分会场,涉及二十多个议题,不要着急,让我们一篇一篇回顾。

本系列回顾文章不是演讲全文的文字稿,而是重点摘要。

主题简介

Guillaume Gomez,华为工程师,rustdoc团队负责人。我的最终目标是使文档的编写尽可能简单,以便所有项目都有很好的文档

Rustdoc是官方的Rust工具,可以为你的crates生成文档。但它所做的远不止这些:它允许你测试你的代码示例,在文档和项目的源代码之间切换,将markdown文件转换为HTML,自动生成项目的链接,显示文档的覆盖范围,它有自己的行数,它允许,等等。

但这还不是全部! 很多更美好的功能即将到来。例如,其中一个功能允许你从源代码页面直接跳到一个项目的定义或其文档页面。

本讲座[1]将介绍这些功能,让你了解rustdoc允许你做什么。

演讲摘要

什么是 rustdoc

rustdoc 是和 Rust 编译器 rustc 一起提供的工具,用于生成代码的文档。通过 cargo doc 命令开发者就可以用其生成文档。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
# 创建项目
> cargo new --lib basic
# 生成文档
> cargo doc
# 使用 --open 参数直接从浏览器打开文档
> cargo doc --open 

rustdoc 生成的文档页面功能非常丰富:

  • 有搜索框,可以搜索你的crate定义的类型、trait和函数等
  • 可以通过 [src]链接来查看源吗
  • 文档示例中的代码可以通过 Run按钮一键打开 playground
  • 其他

很多功能 Guillaume 在演讲视频中也做了分享,可以自行摸索。

如何用 rustdoc 创建文档

在 Rust 里可以通过基本的文档注释 /////!来创建文档, Guillaume 在演讲视频中也做了演示,因为这是最基本的语法,本文里就不做过多介绍。

“注:虽然 Rust 文档支持 Markdown,Guillaume 在演讲中说也可以支持图片,但实际上 rustdoc 中支持图片并没有普通 Markdown 文件那么方便。参加 issues 32104[2] 。有第三方库可以方便地让文档支持图片,embed-doc-image[3]。对于 svg,可以直接用 #![doc=include_str!("shared-bus.svg")]

使用 rustdoc 进行文档测试

文档注释中的代码示例,可以通过 cargo test来运行,这是 rustdoc 提供的文档测试功能。利用文档测试可以做很多事情,比如:

  • 在编写宏的时候,可以将文档测试中的代码设置为测试时编译失败
  • 在一些场景中忽略某些测试代码
  • 其他

相关设置:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
// 使用 ignore 可以让测试忽略代码
/// ```ignore
/// fn foo() {
/// ```

// should_panic 告诉 rustdoc 代码应该正确编译,但在执行过程中会出现恐慌
// 如果代码没有恐慌,测试将失败。
/// ```should_panic
/// assert!(false);
/// ```

// no_run属性将编译代码但不运行它
// 在一些希望编译但没有运行环境的场景下可以使用它
// 也可以演示一些导致未定义行为的代码片段
/// ```no_run
/// loop {
///     println!("Hello, world");
/// }
/// ```

// compile_fail告诉rustdoc编译应该失败
// 如果它编译,那么测试将失败
/// ```compile_fail
/// let x = 5;
/// x += 2; // shouldn't compile!
/// ```


// edition2015,edition2018 和 edition2021 用于告诉rustdoc,
// 代码示例应该使用相应版本的 Rust 编译
/// Only runs on the 2018 edition.
///
/// ```edition2018
/// let result: Result<i32, ParseIntError> = try {
///     "1".parse::<i32>()?
///         + "2".parse::<i32>()?
///         + "3".parse::<i32>()?
/// };
/// ```

文档内链接

Rustdoc 能够使用项目的路径作为链接直接链接到其他 rustdoc 页面。这被称为“文档内链接”。其语法与 Markdown 添加链接语法略有不同。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
// 下面这几种方式都可以链接到 Bar

/// This struct is not [Bar]
pub struct Foo1;

/// This struct is also not [bar](Bar "bar")
pub struct Foo2;

/// This struct is also not [bar][b]
///
/// [b]: Bar
pub struct Foo3;

/// This struct is also not [`Bar`]
pub struct Foo4;

/// This struct *is* [`Bar`]!
pub struct Bar;

use std::sync::mpsc::Receiver;

// rustdoc 支持链接到 标准库文档中的类型

/// This is a version of [`Receiver<T>`] with support for [`std::future`].
///
/// You can obtain a [`std::future::Future`] by calling [`Self::recv()`].
pub struct AsyncReceiver<T> {
    sender: Receiver<T>
}

impl<T> AsyncReceiver<T> {
    pub async fn recv() -> T {
        unimplemented!()
    }
}

/// This is a special implementation of [positional parameters].
///
/// [positional parameters]: std::fmt#formatting-parameters
struct MySpecialFormatter;

// 可以使用 `@` 来消除同名歧义

// 指定是 结构体 Foo
/// See also: [`Foo`](struct@Foo "`Foo`")
/// This struct *is* [`Bar`]!
pub struct Bar;

// 指定是函数 Foo
/// This is different from [`Foo`](fn@Foo "`Foo`")
pub struct Foo {}

pub fn Foo() {}

链接一般以语言项(item)定义的模块为解析范围,哪怕 item 被重导出也一样。如果来自另一个 crate 的链接无法被解析则会发出警告。

“注意:由于macro_rules! 宏的文档内链接 将相对于 crate root[4]进行解析,而不是定义它的模块。

rustdoc lint

rustdoc提供 lints 来帮助开发者编写和测试文档。比如:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
#![allow(rustdoc::broken_intra_doc_links)] // allows the lint, no diagnostics will be reported
#![warn(rustdoc::broken_intra_doc_links)] // warn if there are broken intra-doc links
#![deny(rustdoc::broken_intra_doc_links)] // error if there are broken intra-doc links

这些lint 仅在执行 rustdoc 时可用。

rustdoc lints 可以作以下分类:

  • 默认产生警告的lints
    • BROKEN_INTRA_DOC_LINKS
    • PRIVATE_INTRA_DOC_LINKS
    • INVALID_CODEBLOCK_ATTRIBUTES
    • BARE_URLS
    • INVALID_RUST_CODEBLOCK
  • 默认允许的 lints
    • MISSING_CRATE_LEVEL_DOCS
    • MISSING_DOC_CODE_EXAMPLES
    • PRIVATE_DOC_TESTS
    • INVALID_HTML_TAGS

详细解释可以参阅 rustdoc book。

文档注释工作机制

代码中的文档注释 /// 在编译时会被 #[doc] 属性替换。比如:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
/// This struct is not [Bar]
pub struct Foo1;

被替换为:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
#[doc = " This struct is not [Bar]" ]
pub struct Foo1;

所以,///#[doc] 属性宏的语法糖。

知道这个知识点有什么用呢?利用 #[doc] 允许我们可以更好地编写文档。

可以把 README 复用为文档注释
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
#[doc = include_str!("../../README.md")]
可以设置别名
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
#[doc(alias = "TheAlias")]
pub struct SomeType;

在文档中可以按设置的别名进行搜索,此功能在 FFi 时非常有用:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
pub struct Obj {
    inner: *mut ffi::Obj,
}

impl Obj {
    #[doc(alias = "lib_name_do_something")]
    pub fn do_something(&mut self) -> i32 {
        unsafe { ffi::lib_name_do_something(self.inner) }
    }
}

这样就可以在文档中按被包装的 C 方法原函数名(lib_name_do_something)去搜索到 Obj::do_something

关于 rustdoc 还有很多功能可以去 rustdoc book 中查阅。

延伸阅读

  • rustdoc book[5]
  • Nightly 下 rustdoc 功能[6]

参考资料

[1]

本讲座: https://www.bilibili.com/video/BV1eg411C77X

[2]

32104: https://github.com/rust-lang/rust/issues/32104

[3]

embed-doc-image: https://github.com/Andlon/embed-doc-image

[4]

相对于 crate root: https://github.com/rust-lang/rust/issues/72243

[5]

rustdoc book: https://doc.rust-lang.org/rustdoc/what-is-rustdoc.html

[6]

Nightly 下 rustdoc 功能: https://doc.rust-lang.org/rustdoc/unstable-features.html

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2022-09-01,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 觉学社 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
听GPT 讲Rust源代码--src/librustdoc
题图来自 Why is building a UI in Rust so hard?[1]
fliter
2023/11/22
2590
听GPT 讲Rust源代码--src/librustdoc
Rust项目中的Labels
按照issue数量从多到少排序: https://github.com/rust-lang/rust/labels?page=2&sort=count-desc,仅列出前几页
fliter
2024/02/26
1680
Rust项目中的Labels
Rust API 指南:文档
每个公共模块,特型,结构,枚举,函数,方法,宏和类型定义都应具有一个示例,用于该功能的练习。
袁承兴
2020/12/10
2.1K0
Rust API 指南:文档
基于 actix、async-graphql、rbatis 构建异步 Rust GraphQL 服务(3)- 重构
首先,我们通过 shell 命令 cd ./actix-web-async-graphql-rbatis/backend 进入后端工程目录(下文中,将默认在此目录执行操作)。
niqin.com
2022/06/30
1.4K0
基于 actix、async-graphql、rbatis 构建异步 Rust GraphQL 服务(3)- 重构
rust 代码组织结构
这是 Cargo 的概念,对应一个 Cargo.toml 文件,也就是一个 rust 工程。用于构建、测试、共享 Crate。
jgrass
2024/12/25
1040
rust 代码组织结构
Rust FFI 编程 - bindgen 使用示例
当我们拥有一组具有良好声明的头文件时,自己定义 C 库的 Rust FFI 绑定函数是毫无意义的。我们可以使用 bindgen 这种工具从 C 库的头文件生成 Rust FFI 绑定函数。然后,我们运行一些测试代码以验证其是否正常运行,并对它们进行调整,直到正确为止。
MikeLoveRust
2020/09/30
2.1K0
从 RUST 库中公开 FFI
Wikipedia 将 FFI 定义为一种机制,通过这种机制,用一种编程语言编写的程序可以调用或使用用另一种编程语言编写的服务。
MikeLoveRust
2019/07/09
1.9K0
Rust FFI 编程 - Rust 语言层面对 FFI 的支持
Rust 语言对 FFI 有比较完善的支持。本节主要讲在基础设施层面,Rust 语言对 FFI 的支持。
MikeLoveRust
2020/04/20
3.3K0
听GPT 讲Rust源代码--src/tools(6)
在Rust源代码中,references.rs文件位于rust-analyzer工具的ide模块中,其作用是实现了用于搜索引用的功能。
fliter
2023/12/04
3250
听GPT 讲Rust源代码--src/tools(6)
【Rust日报】2022-05-20 - 用 Rust 扩展 SQLite
作为进程内数据库,SQLite 具有其他扩展机制,例如 用户定义函数(简称 UDF)。但是UDF有一些缺点:
MikeLoveRust
2022/06/10
7710
【Rust日报】2020-07-15 用Rust重写FORTRAN科学软件
chubaodb 是一个分布式高可用的云原生,同时支持传统的分布式文档搜索及存储系统,支持全文检索,聚合查询,向量搜索,标量搜索的功能,采用轻schema策略,尽可能提高了存储文档的灵活度。同时吸取其他类似软件的经验,初心于在有限的计算节点情况下,支持不限容量的存储及计算,同时尽可能低的学习成本,完成尽可能多的需求。
MikeLoveRust
2020/07/17
6190
【Rust日报】2024-03-26 Rust target 目录的磁盘空间问题讨论
一位 Reddit 用户在反映,在他们的 1TB 机器上,一个 target 目录占用了高达 165GB 的空间,总共有近 500GB 的 target 目录空间被占用。
MikeLoveRust
2024/04/01
3310
【Rust日报】2024-03-26 Rust target 目录的磁盘空间问题讨论
听GPT 讲Rust源代码--src/tools(33)
文件rust/src/tools/clippy/clippy_lints/src/std_instead_of_core.rs是Clippy工具中的一个lint源代码文件,用于检查在Rust程序中使用了标准库(std)而不是核心库(core)的情况。
fliter
2024/01/28
1220
听GPT 讲Rust源代码--src/tools(33)
Rust FFI 编程 - Rust导出共享库03
我们已经了解了,Rust语言是多泛式(混合泛式)的语言,它可以做命令式(过程式)编程,也可以做面向对象编程,也可以做函数式编程。把Rust简单地归类为某种泛式的编程语言,都不太合适。Rust就是Rust。
MikeLoveRust
2020/08/04
8620
听GPT 讲Rust Cargo源代码(3)
在Rust Cargo的源代码中,cargo/src/bin/cargo/commands/fix.rs文件的作用是实现了cargo fix命令。cargo fix命令用于自动修复源代码中的一些错误和不规范的代码风格,以提高代码的可读性、可维护性和性能。
fliter
2024/04/25
1540
听GPT 讲Rust Cargo源代码(3)
【译】设计优雅的 Rust 库 API
原文见:https://deterministic.space/elegant-apis-in-rust.html
MikeLoveRust
2019/11/24
1.8K0
【Rust每周一知】 Attribute 属性
Rust 中的属性数量非常多。而且具有可扩展性(可自定义属性)。Rust 的属性语法遵从 C# 定义并标准化了的属性规范ECMA-334。
MikeLoveRust
2020/03/04
4.4K0
基于 actix、async-graphql、rbatis、pgsql/mysql 构建 GraphQL 服务(4)-变更服务
前 3 篇文章中,我们初始化搭建了工程结构,选择了必须的 crate,并成功构建了 GraphQL 查询服务,以及对代码进行了第一次重构。本篇文章,是我们进行 GraphQL 服务后端开发的最后一篇:变更服务。本篇文章之后,GraphQL 服务后端开发第一阶段告一阶段,之后我们进行 基于 Rust 的 Web 前端开发。本系列文章中,采用螺旋式思路,Web 前端基础开发之后,再回头进行 GraphQL 后端开发的改进。
niqin.com
2022/06/30
1.3K0
基于 actix、async-graphql、rbatis、pgsql/mysql 构建 GraphQL 服务(4)-变更服务
初识Rust
虽然我主要使用C++,但是最近也想学点现代化的新语言。初步想的是从golang和Rust里先选一个。
owent
2018/08/01
1.6K0
第2章 | Rust 导览
安装 Rust 的最佳方式是使用 rustup。请转到 rustup.rs 网站并按照那里的说明进行操作。
草帽lufei
2024/05/08
1290
第2章 | Rust 导览
相关推荐
听GPT 讲Rust源代码--src/librustdoc
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
本文部分代码块支持一键运行,欢迎体验
本文部分代码块支持一键运行,欢迎体验