如何在 Rust 编译期间检查功能集?

7
我正在尝试使用Rust的功能在我的crate中有条件地编译一个模块,并且仅在启用某个特性时使用它。当设置了特性时,有条件的编译工作正常,但在未设置特性时拒绝编译。
我在主要代码中使用相同的特性标志来有条件地导入模块,因此我的假设是在不使用该特性时不应该导入该模块。
#[cfg(feature = "debug")]
pub mod k {
    pub struct S { pub x: i32, pub y: i32}
}

我如何在主要程序中使用它

pub fn main() {
    if cfg!(feature = "debug") {
        use self::k;
        let _s = k::S {x: 4, y: 5};
    }

    let g = vec![1, 2, 4];
    println!("{:?}", g);
}

如果我使用--features标志启用该功能,那么它将按预期编译:
cargo build --features "debug" 
    Finished dev [unoptimized + debuginfo] target(s) in 0.08s

但是当我没有传递--features时,它会失败,我的期望是它应该跳过具有cfg!设置的代码块。

error[E0432]: unresolved import `self::k`
  --> src/main.rs:32:13
   |
32 |         use self::k;
   |             ^^^^^^^ no `k` in the root

error: aborting due to previous error

For more information about this error, try `rustc --explain E0432`.

这是我的 Cargo.toml 文件的样子。
[features]
default = []
debug = []

有人能解释一下为什么会发生这种情况并提供更好的条件编译代码块的方法吗?

可能是如何为条件编译标记使用语句?的重复问题。 - Stargateur
@Stargateur 没有特别的原因。我基于一个旧模板来创建我的小项目,似乎它有主要公共部分。我已经修复了它。感谢你指出来。 - draklor40
@Stargateur 不完全正确,尽管我知道我可能犯了错误。如果未启用 debug,则在编译期间 if cfg!(feature = "debug") { 将被替换为类似于 if false 的内容,但是接下来的两行仍将被编译。但是,只有在启用 feature = debug 时才会编译 mod k,因此编译器会抱怨缺少模块。我可以用 #[cfg(feature = "debug")] 替换 if else,然后跟随一个块,在其中创建我需要的结构体。 - draklor40
@draklor40,你是对的,“cfg!”会被评估为一个表达式,而不是一个属性。 - sn99
1个回答

2

我看到评论中你已经找到了解决方案。

但是如果您想根据功能标志创建变量怎么办?

这是我的想法:

#[cfg(feature = "debug")]
pub mod k {
    pub struct S { pub x: i32, pub y: i32}
}

pub fn main() {
    #[cfg(feature = "debug")]
    let variable = {
        use self::k;
        let _s = k::S {x: 4, y: 5};
        // this is now a struct
        _s
    };

    #[cfg(not(feature = "debug"))]
    let variable = {
        // this is now a string
        String::from("same variable; \
        different data types depending on feature flags")
        
    };

    println!("conditional compilation is cool:\n{:?}", variable);
}

playground

基本上,它就像cfg!(feature = "debug")。不同之处在于cfg!宏内部的内容必须在编译时有效,这意味着数据类型或方法必须存在于当前作用域中才能调用。

因此,例如,在cfg!-if语句中不能使用有条件编译的结构体。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接