cfg-if = "1.0.0"然后,在代码中使用 cfg_if! 宏:
use cfg_if::cfg_if; cfg_if! { if #[cfg(unix)] { fn foo() { /* unix-specific functionality */ } } else if #[cfg(windows)] { fn foo() { /* windows-specific functionality */ } } else { fn foo() { /* fallback implementation */ } } }可以看到使用这个库的优势:
可组合: 可以轻松组合多个条件。
cfg_if! { if #[cfg(all(unix, target_pointer_width = "32"))] { // 32-bit unix systems } else if #[cfg(all(unix, target_pointer_width = "64"))] { // 64-bit unix systems } else if #[cfg(windows)] { // windows systems } else { // other systems } }cfg_if 宏在编译时展开,生成等效的 if-else 链 或 match 表达式。这意味着它没有运行时开销,所有的条件检查都在编译时完成。
4.API 兼容性层
2.过度使用可能会使代码难以理解,应适度使用。
#[cfg()] #[cfg()] 是 Rust 的一个内置属性,用于条件编译。它允许您根据指定的配置选项来包含或排除代码。这是 Rust 中进行条件编译的主要方式, 例如: #[cfg(unix)] fn unix_only() { // 这个函数只在 Unix 系统上编译 } #[cfg(windows)] fn windows_only() { // 这个函数只在 Windows 系统上编译 }常用的配置选项:
#[cfg(all(unix, target_pointer_width = "64"))] fn unix_64bit_function() { // 只在 64 位 Unix 系统上编译 } #[cfg(any(windows, macos))] fn windows_or_mac_function() { // 在 Windows 或 macOS 上编译 } #[cfg(not(debug_assertions))] fn release_only() { // 只在 release 模式下编译 }它可以应用在多个场景:
#[cfg(feature = "advanced")] mod advanced_features { // 这个模块只在启用 "advanced" 特性时编译 }2、条件导入
#[cfg(unix)] use std::os::unix::fs::MetadataExt; #[cfg(windows)] use std::os::windows::fs::MetadataExt;3、在代码中使用
if cfg!(debug_assertions) { println!("Debug mode"); } else { println!("Release mode"); }4、甚至可以使用自定义标志 在 Cargo.toml 中定义自己的特性标志:
[features] my_feature = []然后在代码中使用:
#[cfg(feature = "my_feature")] fn feature_specific_function() { // ... }总得来说,Rust 的 cfg 属性和 cfg! 宏支持多种逻辑组合。以下是完整的列表:
all: 所有条件都必须为真 #[cfg(all(unix, target_pointer_width = "64"))] any: 任意一个条件为真即可 #[cfg(any(windows, macos))] not: 条件必须为假 #[cfg(not(windows))] target_os: 目标操作系统 #[cfg(target_os = "linux")] target_arch: 目标架构 #[cfg(target_arch = "x86_64")] target_feature: 特定的 CPU 特性 #[cfg(target_feature = "avx2")] target_endian: 字节序 #[cfg(target_endian = "little")] target_pointer_width: 指针宽度 #[cfg(target_pointer_width = "64")] target_env: 目标环境 #[cfg(target_env = "gnu")] target_vendor: 目标供应商 #[cfg(target_vendor = "apple")] feature: 编译时特性 #[cfg(feature = "my_feature")] debug_assertions: 是否启用调试断言 #[cfg(debug_assertions)] test: 是否在测试模式下编译 #[cfg(test)] 这些条件可以任意组合使用: #[cfg(all(unix, not(any(target_os = "macos", target_os = "ios"))))]此外,还可以使用 cfg_attr 来条件性地应用其他属性(第一个参数是条件,第二个参数是条件为真时的属性):
#[cfg_attr(feature = "nightly", feature(some_unstable_feature))] ... #[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] struct MyStruct { // fields... }记住,这些配置可以在编译时使用 --cfg 标志来设置,也可以在 Cargo.toml 中通过 features 来控制。使用这些逻辑组合,你可以非常精细地控制哪些代码在特定条件下被编译。
#[cfg()] 在编译时评估,不会增加运行时开销。 cfg_if vs cfg #[cfg()] 是 Rust 的内置功能,不需要额外的依赖。对于简单的条件,#[cfg()] 通常更直接。