当前位置:   article > 正文

rust中常用cfg属性和cfg!宏的使用说明,实现不同系统的条件编译

rust中常用cfg属性和cfg!宏的使用说明,实现不同系统的条件编译

cfg有两种使用方式,一种是属性: #[cfg()],一种是宏:cfg! ,这两个都是非常常用的功能。

#[cfg()]是 Rust 中的一个属性

用于根据配置条件来选择性地包含或排除代码。cfg 是 "configuration" 的缩写,用于控制在不同的构建环境或平台上编译和执行不同的代码块。在不同的操作系统上会编译不同的函数示例:

  1. #[cfg(target_os = "linux")]
  2. fn get_os_info(){
  3. println!("linux");
  4. }
  5. #[cfg(target_os = "windows")]
  6. fn get_os_info() {
  7. println!("windows");
  8. }
  9. fn main() {
  10. get_os_info();
  11. }

也可使用not表达式:在非 linux 系统下会编译此函数

  1. #[cfg(not(target_os = "linux"))]
  2. fn get_os_info() {
  3. println!("not linux");
  4. }

#[cfg()] 属性可以用于函数、结构体、枚举、模块、模块导入等各种代码元素,以及条件编译块(#[cfg()] 包围的代码块)。它使用一个或多个条件表达式来指定编译时要包含或排除的代码。条件表达式可以是 Rust 的预定义属性、环境变量、操作系统类型、目标架构等。

#[cfg()] 属性中使用的逻辑运算符有以下几种:

  1. all(expr1, expr2, ...):逻辑与运算符,要求所有条件表达式都为真才返回真。例如:#[cfg(all(feature = "foo", target_os = "linux"))] 表示只有在启用 "foo" 功能并且目标操作系统是 Linux 时条件成立。
  2. any(expr1, expr2, ...):逻辑或运算符,只要有任一条件表达式为真就返回真。例如:#[cfg(any(feature = "foo", feature = "bar"))] 表示只要启用 "foo" 或 "bar" 中的任意一个功能时条件成立。
  3. not(expr):逻辑非运算符,对条件表达式取反。例如:#[cfg(not(debug_assertions))] 表示只有在非调试断言模式下条件成立。

以下是一些示例用法:

  1. #[cfg(target_os = "linux")]
  2. fn only_on_linux() {
  3. // 仅在 Linux 系统上编译和执行的代码
  4. }
  5. #[cfg(all(unix, not(target_os = "linux")))]
  6. fn on_unix_but_not_linux() {
  7. // 仅在 Unix 系统但不是 Linux 上编译和执行的代码
  8. }
  9. #[cfg(any(windows, target_os = "macos"))]
  10. fn on_windows_or_macos() {
  11. // 仅在 Windows 或 macOS 上编译和执行的代码
  12. }
  13. #[cfg(not(debug_assertions))]
  14. fn when_not_debug_assertions() {
  15. // 仅在非调试断言模式下编译和执行的代码
  16. }
  17. #[cfg(feature = "my_feature")]
  18. fn with_my_feature_enabled() {
  19. // 仅在启用 "my_feature" 功能时编译和执行的代码
  20. }

在这些示例中,#[cfg()] 属性根据不同的条件表达式来控制代码的编译和执行。根据配置条件的不同,编译器会选择性地包含或排除相应的代码。

#[cfg()] 属性可以根据不同的需求来组合条件表达式,并支持各种逻辑运算符(如 allanynot)来组合条件。你可以根据特定的配置条件来编写平台特定的代码、功能开关的代码、调试模式的代码等。

注意:#[cfg()] 属性是在编译时进行判断和处理的,不会在运行时起作用。因此,通过使用不同的配置条件,你可以在不同的构建环境中选择性地编译和执行特定的代码块

cfg!宏的方法

判断操作系统,执行不同的代码块:

  1. if cfg!(target_os = "linux") {
  2. println!("linux");
  3. } else {
  4. println!("not linux");
  5. }

比如执行cmd命令还是shell命令:

  1. use std::process::Command;
  2. // cmd_str可以是从输入流读取或从文件里读取
  3. let cmd_str: String;
  4. if cfg!(target_os = "windows") {
  5. // 这里不用\\而是/的话会被windows认为/tmp的/t是一个option而报错
  6. cmd_str = "dir d:\\tmp".to_string();
  7. } else {
  8. cmd_str = "dir /usr/tmp".to_string();
  9. }
  10. let output = if cfg!(target_os = "windows") {
  11. Command::new("cmd").arg("/c").arg(cmd_str).output().expect("cmd exec error!")
  12. } else {
  13. Command::new("sh").arg("-c").arg(cmd_str).output().expect("sh exec error!")
  14. }
  15. let output_str = String::from_utf8_lossy(&output.stdout);
  16. println!("{}", output_str);
声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/菜鸟追梦旅行/article/detail/343774
推荐阅读
相关标签
  

闽ICP备14008679号