特性示例

下面说明一些实际中的特性示例。

最大限度地减少构建时间和文件大小

一些包使用了特性,如果不启用这些特性,就会减小crate的大小并减少编译时间。一些例子是:

  • syn 是用于解析Rust代码的crate,对于减少编译时间很有帮助,是个流行的项目。 它有一个 清晰记录列表 的特性,可以用来减少所包含的代码量。
  • regex几个特性 ,这些特性都有 很好的文档 。 移除Unicode支持,将删除一些很大表,可以减少产生文件的大小。
  • winapi大量 的特性,以限制它支持哪些Windows API绑定。
  • web-sys 是另一个类似于 winapi 的例子,它提供了 大量 的API绑定,可以使用特性限制这些绑定。

扩展行为

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

当改变这样的行为时,要注意确保这些改变是 语义化兼容 的。 也就是说,启用该特性不应该破坏通常在该特性关闭时构建的代码。

no_std 支持

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

wasm-bindgen 包定义了 std 特性默认启用 。 在库的顶部,它 非可选的启用 no_std 属性 。 这确保了 stdstd prelude 不会自动进入作用域。 然后,在代码的不同地方( example1 , example2 ),它使用 #[cfg(feature = "std")] 属性,有条件地启用需要 std 的附加功能。

重新导出依赖特性

从依赖中重新导出特性可能是很方便的。 这允许依赖于 crate 的用户控制这些特性,而不需要直接指定这些依赖。 例如, regex 重新导出特性 来自 regex_syntax 包。 regex 的用户不需要知道 regex_syntax 包,但他们仍然可以访问它所包含的功能。

C库支持

一些包提供了与普通C库的绑定(有时被称为 "sys" crates) 。 有时,这些包让你选择使用系统上安装的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" 级别将优先于较低的级别。

过程宏协同包

有些包有一个与之紧密相连的过程宏。然而,并不是所有的用户都需要使用这个过程宏。 通过使过程宏成为可选的依赖,这允许你方便地选择是否包含它。 这很有帮助,因为有时过程宏的版本必须与父包保持同步,而你不想强迫用户必须指定两个依赖并保持它们同步。

一个例子是 serde ,它有一个 derive 特性,可以启用 serde_derive 过程宏。 serde_derive crate与 serde 紧密关联,所以它使用 相同版本要求 来确保它们保持同步。

每日构建特性

一些包想要试验只有在 Rust nightly channel 上才有的API或语言特性。 然而,他们可能不希望要求用户也使用nightly频道。 一个例子是 wasm-bindgen ,它有一个 nightly 特性 , 它启用了 扩展的API ,使用 Unsize 标记特性,在写这篇文章时,只有在nightly频道中才有。

请注意,在crate的root,它使用了 cfg_attr 来启用每日特性 。 要知道, feature 属性 与Cargo特性无关,它是用来选择加入实验性语言特性的。

rand 包的 simd_support 特性 是另一个例子,它依赖于一个只在每日频道构建的依赖。

实验特性

一些包有新的特性,他们可能想进行实验,而不必承诺这些API的稳定性。 这些特性通常被记录在案,它们是实验性的,因此在未来可能会发生变化或损坏,甚至是在一个次要的版本中。 一个例子是 [async-std] 包,它有一个 [unstable] 特性 async-std-unstablegates new APIs ,人们可以选择使用,但可能还没有完全准备好被依赖。