功能示例
以下说明了一些实际的功能使用示例。
最小化构建时间和文件大小
一些包使用功能,以便在未启用这些功能时,可以减小包的大小并缩短编译时间。以下是一些例子:
syn
是一个流行的用于解析 Rust 代码的包。由于它非常流行,因此减少编译时间非常有帮助,因为它会影响许多项目。它有一个 清晰记录的功能列表,可用于最小化其包含的代码量。regex
有 几个功能,这些功能 有详细的文档记录。关闭 Unicode 支持可以减小生成的文件大小,因为它可以删除一些大型表。winapi
有 大量的功能,这些功能限制了它支持的 Windows API 绑定。web-sys
是另一个类似于winapi
的例子,它提供了 巨大的 API 绑定表面积,这些绑定通过使用功能进行限制。
扩展行为
serde_json
包有一个 preserve_order
功能,它 改变了 JSON 映射的行为,以保留插入键的顺序。请注意,它启用了可选依赖项 indexmap
来实现新行为。
更改此类行为时,请注意确保更改 与语义化版本兼容。也就是说,启用该功能不应破坏通常在禁用该功能的情况下构建的代码。
no_std
支持
一些包希望同时支持 no_std
和 std
环境。这对于支持嵌入式和资源受限的平台非常有用,但仍然允许支持完整标准库的平台扩展功能。
wasm-bindgen
包定义了一个 std
功能,该功能 默认启用。在库的顶部,它 无条件地启用了 no_std
属性。这确保了 std
和 std
前奏 不在范围内自动可用。然后,在代码的各个地方(示例 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,但可能还没有完全准备好依赖它们。