我是 Rust 的新手,尝试阅读一些项目来学习。在这个 binance api 连接器 Rust 项目中。某些依赖项设置为可选,但其他依赖项则不是。有些依赖项应该设置为可选,而有些依赖项则不应该设置为可选,这是出于什么考虑?
[features]
default = ["enable-ureq", "enable-tungstenite"]
enable-hyper = [ "hyper", "hyper-tls", "serde_json", "futures-util", "tokio" ]
enable-ureq = [ "ureq", "serde_json" ]
enable-tungstenite = ["tungstenite"]
enable-tokio-tungstenite = ["tokio-tungstenite"]
full = ["enable-hyper", "enable-tungstenite", "enable-ureq", "enable-tokio-tungstenite"]
[dependencies]
hmac = "0.12.0"
log = "0.4.14"
serde = { version = "1.0.136", features = ["derive"] }
sha2 = { version = "0.10.6", default-features = false, features = ["oid"] }
url = "2.2.2"
rust_decimal = "1.24.0"
http = "0.2.7"
strum = { version = "0.24", features = ["derive"] }
rand = "0.8.5"
signature = "2.2.0"
base64 = "0.13.1"
ed25519-dalek = { version = "2.1.0", features = ["serde", "zeroize", "rand_core", "digest", "pkcs8", "pem"] }
# enable-ureq
ureq = { version = "2.4.0", optional = true }
# enable-hyper
hyper = { version = "0.14.16", features = ["full"], optional = true }
serde_json = { version = "1.0.78", optional = true }
hyper-tls = {version = "0.5.0", optional = true }
futures-util = {version = "0.3.21", optional = true }
tokio = { version = "1", features = ["time"], optional = true }
# enable-tungstenite
tungstenite = {version = "0.20.1", features = ["native-tls"], optional = true}
# enable-tokio-tungstenite
tokio-tungstenite = {version = "0.17.1", features = ["native-tls"], optional = true}
有关在 rust Cargo.toml 中使依赖项成为可选的标准的说明
除非由功能启用,否则不会编译可选依赖项。
您可以在上面看到此板条箱的一组
[features]
("enable-hyper"
、"enable-ureq"
等),其中default
功能会自动启用,除非禁用(通过依赖板条箱中的default-features = false
或--no-default-features
参数)本地构建时)。这里的作者很友善地将 optional = true
依赖项分开分组,甚至还用标题注释记录了哪些功能启用了它们。
何时将依赖项设置为可选?
仅当您不想编译板条箱中的某些部分(除非需要该部分)时,才应将它们设置为可选。将依赖项保留为可选意味着最终用户可以避免下载和构建这些依赖项(如果他们不使用它们的用途)。
第三方库支持(hyper、ureq等)是很好的利用特性和可选依赖项。
您不应该不必要地这样做,因为确实依赖于这些可选依赖项的包中的代码需要进行功能门控,以确保当依赖项不存在时它们不会被编译。过度使用可能会导致无法维护。例如,如果该库公开了这样一个使用 ureq 箱的函数,则可以使用条件编译注释来编写,如下所示:
#[cfg(feature = "enable-ureq")]
pub fn use_ureq() {
use ureq::*; // the ureq dependency is available here
...
}
因此,如果相关用户未启用
"enable-ureq"
功能(或在这种情况下将其保留为默认值),那么他们将无法调用 use_ureq
功能。
如果您的功能没有很好地隔离,还有另一个潜在的负担:可能很难测试所有已启用功能的组合是否实际上都是可编译的。请参阅此处的问答以获取相关帮助。