Rust 使用'cfg!'的正确方法是什么宏在多个实现之间进行选择?

Rust 使用'cfg!'的正确方法是什么宏在多个实现之间进行选择?,rust,Rust,我在Cargo.toml中指定了一些特性: [features] complex = [] simple = [] 当我构建项目时,我使用cargo build--features=“complex”或simple 在某些函数中,我希望根据使用的功能返回一个值: fn test() -> u32 { let x: u32 = 3; if cfg!(feature = "complex") { let y: u32 = 2; x + y

我在Cargo.toml中指定了一些特性:

[features]
complex = []
simple = []
当我构建项目时,我使用
cargo build--features=“complex”
simple

在某些函数中,我希望根据使用的功能返回一个值:

fn test() -> u32 {
    let x: u32 = 3;
    if cfg!(feature = "complex") {
        let y: u32 = 2;
        x + y
    }
    if cfg!(feature = "simple") {
        let y: u32 = 1;
        x + y
    }
}
但这不起作用,因为它试图计算这两个表达式。使用
cfg的正确方法是什么宏在我的情况下?

状态:

配置标志的布尔计算

这意味着
cfg!(…)
替换为布尔值(
true
/
false
)。扩展后,您的代码将如下所示:

fn test() -> u32 {
    let x = 3;
    if true {
        let y = 2;
        x + y
    }
    if true {
        let y = 1;
        x + y
    }
}
最简单的解决方案是添加一个
else

fn test() -> u32 {
    let x = 3;
    if cfg!(feature = "complex") {
        let y = 2;
        x + y
    } else {
        let y = 1;
        x + y
    }
}
您还可以使用属性形式
cfg
。在这种情况下,该属性会阻止编译整个下一个表达式:

fn test() -> u32 {
    let x: u32 = 3;

    #[cfg(feature = "complex")]
    {
        let y: u32 = 2;
        x + y
    }

    #[cfg(feature = "simple")]
    {
        let y: u32 = 1;
        x + y
    }
}
因为它试图计算这两个表达式


不,没有。计算发生在运行时,甚至无法编译此代码

另见:

    • 各州:

      配置标志的布尔计算

      这意味着
      cfg!(…)
      替换为布尔值(
      true
      /
      false
      )。扩展后,您的代码将如下所示:

      fn test() -> u32 {
          let x = 3;
          if true {
              let y = 2;
              x + y
          }
          if true {
              let y = 1;
              x + y
          }
      }
      
      最简单的解决方案是添加一个
      else

      fn test() -> u32 {
          let x = 3;
          if cfg!(feature = "complex") {
              let y = 2;
              x + y
          } else {
              let y = 1;
              x + y
          }
      }
      
      您还可以使用属性形式
      cfg
      。在这种情况下,该属性会阻止编译整个下一个表达式:

      fn test() -> u32 {
          let x: u32 = 3;
      
          #[cfg(feature = "complex")]
          {
              let y: u32 = 2;
              x + y
          }
      
          #[cfg(feature = "simple")]
          {
              let y: u32 = 1;
              x + y
          }
      }
      
      因为它试图计算这两个表达式


      不,没有。计算发生在运行时,甚至无法编译此代码

      另见:


      惯用Rust不使用冗余类型注释。函数体中的所有
      :u32
      都应该删除。惯用Rust不使用冗余类型注释。应该删除函数体中的所有
      :u32
      。“计算发生在运行时,此代码甚至无法编译。”-好吧,如果决定在
      cfg下放置
      false
      true
      !(feature=“complex”)
      是在编译时完成的,那么是什么阻止编译器/优化器删除这些分支呢(如果为false,则删除这些分支是因为它是不可访问的,如果为true,则删除这些分支是因为它是无意义的)。因此,在运行时根本不会进行任何计算。@VictorPolevoy您基本上是对的-
      如果为false
      如果为true
      应在编译时删除,至少在优化时是这样。如果为false,则应删除
      的正文,但如果为true,则应保留正文。然后,无论哪个块
      true
      都将在运行时进行计算。这是使用
      else
      的另一个原因-防止对两个功能的代码块进行评估!还要注意的是,这种类型的优化不应该改变程序的行为。@Shepmaster,这就是我的意思:)“计算发生在运行时,而且这个代码甚至不能被编译。”-好吧,如果决定在
      cfg下放置
      false
      true
      !(feature=“complex”)
      是在编译时完成的,那么是什么阻止编译器/优化器删除这些分支呢(如果为false,则删除这些分支是因为它是不可访问的,如果为true,则删除这些分支是因为它是无意义的)。因此,在运行时根本不会进行任何计算。@VictorPolevoy您基本上是对的-
      如果为false
      如果为true
      应在编译时删除,至少在优化时是这样。如果为false,则应删除
      的正文,但如果为true,则应保留正文。然后,无论哪个块
      true
      都将在运行时进行计算。这是使用
      else
      的另一个原因-防止对两个功能的代码块进行评估!还要注意,这种类型的优化不应改变程序的行为。@Shepmaster这就是我的意思:)