01-Features 示例

features 的常见用法示例

译文 · 基于 The Cargo Book

Features 示例

原文链接: https://doc.rust-lang.org/cargo/reference/features-examples.html

以下展示一些实际使用中的特性示例。

最小化构建时间与文件大小

一些包使用特性,以便在特性未启用时减小 crate 大小并缩短编译时间。一些示例是:

  • syn 是用于解析 Rust 代码的流行 crate。由于它如此流行,缩短编译时间很有帮助,因为它影响许多项目。它有一份文档清晰的特性列表,可用于最小化其包含的代码量。
  • regex 有若干特性,且文档完善。去掉 Unicode 支持可以减小最终文件大小,因为它可以移除一些大型表。
  • winapi 有大量特性,用于限制它所支持的 Windows API 绑定。
  • web-sys 是另一个与 winapi 类似的示例,它提供由特性限制的巨大 API 绑定表面积。

扩展行为

serde_json 包有一个 preserve_order 特性,它改变 JSON map 的行为以保留键的插入顺序。注意它启用可选依赖 indexmap 以实现新行为。

像这样改变行为时,务必确保变更是 SemVer 兼容的。也就是说,启用该特性不应破坏通常在关闭该特性时能构建的代码。

no_std 支持

一些包希望同时支持 no_std 与 std 环境。这对于支持嵌入式与资源受限平台很有用,同时仍允许支持完整标准库的平台使用扩展能力。

wasm-bindgen 包定义了一个默认启用的 std 特性。在库的顶部,它无条件启用 no_std 属性。这确保 std 与 std prelude 不会自动进入作用域。然后,在代码的各处(示例1、示例2),它使用 #[cfg(feature = "std")] 属性有条件地启用需要 std 的额外功能。

重新导出依赖特性

重新导出依赖的特性可能很方便。这允许依赖该 crate 的用户控制这些特性,而无需直接指定那些依赖。例如,regex 重新导出来自 regex_syntax 包的特性。regex 的用户无需了解 regex_syntax 包,但他们仍可访问它所包含的特性。

供应商化 C 库

一些包提供对常见 C 库的绑定(有时称为 “sys” crate)。有时这些包让你选择使用系统上已安装的 C 库,或从源码构建它。例如,openssl 包有一个 vendored 特性,它启用 openssl-sys 的对应 vendored 特性。openssl-sys 构建脚本有一些条件逻辑,使其从本地 OpenSSL 源码副本构建,而不是使用系统版本。

curl-sys 包是另一个示例,其中 static-curl 特性使其从源码构建 libcurl。注意它还有一个 force-system-lib-on-osx 特性,强制它使用系统 libcurl,覆盖 static-curl 设置。

特性优先级

一些包可能有互斥的特性。处理这一点的一种选项是优先使用某个特性而非另一个。log 包是一个示例。它有若干特性用于在编译时选择最大日志级别,在此处有描述。它使用 cfg-if 来选择优先级。若启用多个特性,较高的「max」级别将优先于较低级别。

Proc-macro 配套包

一些包有与之紧密关联的 proc-macro。然而,并非所有用户都需要使用该 proc-macro。通过将 proc-macro 设为可选依赖,你可以方便地选择是否包含它。这很有帮助,因为有时 proc-macro 版本必须与父包保持同步,而你不希望强迫用户必须指定两个依赖并保持它们同步。

一个示例是 serde,它有一个启用 serde_derive proc-macro 的 derive 特性。serde_derive crate 与 serde 非常紧密地绑定,因此它使用等于版本需求以确保它们保持同步。

仅 Nightly 特性

一些包希望试验仅在 Rust nightly 通道上可用的 API 或语言特性。然而,它们可能不希望也要求用户使用 nightly 通道。一个示例是 wasm-bindgen,它有一个 nightly 特性,启用使用撰写本文时仅在 nightly 通道上可用的 Unsize 标记 trait 的扩展 API。

注意在 crate 根处它使用 cfg_attr 启用 nightly 特性。请记住 feature 属性 与 Cargo 特性无关,用于选择加入实验性语言特性。

rand 包的 simd_support 特性是另一个示例,它依赖一个仅在 nightly 通道上构建的依赖。

实验性特性

一些包有它们可能希望试验的新功能,而不必承诺这些 API 的稳定性。这些特性通常会文档说明它们是实验性的,因此即使在次版本发布中,将来也可能更改或破坏。一个示例是 async-std 包,它有一个 unstable 特性,它门控新 API,人们可以选择加入使用,但可能尚未完全准备好被依赖。

最后修改 August 11, 2026: 更新 (70a5af133)