功能示例

以下说明了一些实际的功能使用示例。

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

一些包使用功能,以便在未启用这些功能时,可以减小包的大小并缩短编译时间。以下是一些例子:

扩展行为

serde_json 包有一个 preserve_order 功能,它 改变了 JSON 映射的行为,以保留插入键的顺序。请注意,它启用了可选依赖项 indexmap 来实现新行为。

更改此类行为时,请注意确保更改 与语义化版本兼容。也就是说,启用该功能不应破坏通常在禁用该功能的情况下构建的代码。

no_std 支持

一些包希望同时支持 no_stdstd 环境。这对于支持嵌入式和资源受限的平台非常有用,但仍然允许支持完整标准库的平台扩展功能。

wasm-bindgen 包定义了一个 std 功能,该功能 默认启用。在库的顶部,它 无条件地启用了 no_std 属性。这确保了 stdstd 前奏 不在范围内自动可用。然后,在代码的各个地方(示例 1示例 2),它使用 #[cfg(feature = "std")] 属性有条件地启用需要 std 的额外功能。

重新导出依赖项功能

重新导出依赖项的功能可能很方便。这允许依赖于该包的用户控制这些功能,而无需直接指定这些依赖项。例如,regex 重新导出了 regex_syntax 包中的功能。regex 的用户不需要了解 regex_syntax 包,但他们仍然可以访问它包含的功能。

C 库的供应商化

一些包提供了对常见 C 库的绑定(有时称为 “sys” 包)。有时,这些包允许您选择使用系统上安装的 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选择优先级。如果启用了多个功能,则较高的“最大”级别将优先于较低的级别。

过程宏伴侣包

一些包有一个与其紧密相关的过程宏。但是,并非所有用户都需要使用过程宏。通过将过程宏设为可选依赖项,您可以方便地选择是否包含它。这很有帮助,因为有时过程宏版本必须与父包保持同步,并且您不想强迫用户必须指定两个依赖项并使它们保持同步。

例如 serde,它有一个 derive 功能,可以启用 serde_derive 过程宏。serde_derive 包与 serde 紧密相连,因此它使用 相等版本要求 来确保它们保持同步。

仅限夜间版本的功能

一些包想要尝试仅在 Rust nightly 频道上可用的 API 或语言功能。但是,他们可能不希望要求他们的用户也使用 nightly 频道。例如 wasm-bindgen,它有一个 nightly 功能,该功能启用了一个 扩展 API,该 API 使用了在撰写本文时仅在 nightly 频道上可用的 Unsize 标记 trait。

请注意,在 crate 的根目录中,它使用 cfg_attr 来启用 nightly 功能。请记住,feature 属性 与 Cargo 功能无关,用于选择加入实验性语言功能。

rand 包的 simd_support 功能 是另一个例子,它依赖于仅在 nightly 频道上构建的依赖项。

实验性功能

一些包具有他们可能想要尝试的新功能,而不必承诺这些 API 的稳定性。这些功能通常被记录为实验性的,因此即使在次要版本中也可能会发生变化或中断。例如 async-std 包,它有一个 unstable 功能,该功能 控制着新的 API,人们可以选择使用这些 API,但可能还没有完全准备好依赖它们。