赞
踩
cfg有两种使用方式,一种是属性: #[cfg()]
,一种是宏:cfg! ,这两个都是非常常用的功能。
#[cfg()]
是 Rust 中的一个属性用于根据配置条件来选择性地包含或排除代码。cfg
是 "configuration" 的缩写,用于控制在不同的构建环境或平台上编译和执行不同的代码块。在不同的操作系统上会编译不同的函数示例:
- #[cfg(target_os = "linux")]
- fn get_os_info(){
- println!("linux");
- }
-
- #[cfg(target_os = "windows")]
- fn get_os_info() {
- println!("windows");
- }
-
- fn main() {
- get_os_info();
- }
也可使用not表达式:在非 linux 系统下会编译此函数
- #[cfg(not(target_os = "linux"))]
- fn get_os_info() {
- println!("not linux");
- }
#[cfg()]
属性可以用于函数、结构体、枚举、模块、模块导入等各种代码元素,以及条件编译块(#[cfg()]
包围的代码块)。它使用一个或多个条件表达式来指定编译时要包含或排除的代码。条件表达式可以是 Rust 的预定义属性、环境变量、操作系统类型、目标架构等。
#[cfg()]
属性中使用的逻辑运算符有以下几种:
all(expr1, expr2, ...)
:逻辑与运算符,要求所有条件表达式都为真才返回真。例如:#[cfg(all(feature = "foo", target_os = "linux"))]
表示只有在启用 "foo" 功能并且目标操作系统是 Linux 时条件成立。any(expr1, expr2, ...)
:逻辑或运算符,只要有任一条件表达式为真就返回真。例如:#[cfg(any(feature = "foo", feature = "bar"))]
表示只要启用 "foo" 或 "bar" 中的任意一个功能时条件成立。not(expr)
:逻辑非运算符,对条件表达式取反。例如:#[cfg(not(debug_assertions))]
表示只有在非调试断言模式下条件成立。以下是一些示例用法:
- #[cfg(target_os = "linux")]
- fn only_on_linux() {
- // 仅在 Linux 系统上编译和执行的代码
- }
-
- #[cfg(all(unix, not(target_os = "linux")))]
- fn on_unix_but_not_linux() {
- // 仅在 Unix 系统但不是 Linux 上编译和执行的代码
- }
-
- #[cfg(any(windows, target_os = "macos"))]
- fn on_windows_or_macos() {
- // 仅在 Windows 或 macOS 上编译和执行的代码
- }
-
- #[cfg(not(debug_assertions))]
- fn when_not_debug_assertions() {
- // 仅在非调试断言模式下编译和执行的代码
- }
-
- #[cfg(feature = "my_feature")]
- fn with_my_feature_enabled() {
- // 仅在启用 "my_feature" 功能时编译和执行的代码
- }
在这些示例中,#[cfg()]
属性根据不同的条件表达式来控制代码的编译和执行。根据配置条件的不同,编译器会选择性地包含或排除相应的代码。
#[cfg()]
属性可以根据不同的需求来组合条件表达式,并支持各种逻辑运算符(如 all
、any
、not
)来组合条件。你可以根据特定的配置条件来编写平台特定的代码、功能开关的代码、调试模式的代码等。
注意:#[cfg()]
属性是在编译时进行判断和处理的,不会在运行时起作用。因此,通过使用不同的配置条件,你可以在不同的构建环境中选择性地编译和执行特定的代码块。
判断操作系统,执行不同的代码块:
- if cfg!(target_os = "linux") {
- println!("linux");
- } else {
- println!("not linux");
- }
比如执行cmd命令还是shell命令:
- use std::process::Command;
-
- // cmd_str可以是从输入流读取或从文件里读取
- let cmd_str: String;
- if cfg!(target_os = "windows") {
- // 这里不用\\而是/的话会被windows认为/tmp的/t是一个option而报错
- cmd_str = "dir d:\\tmp".to_string();
- } else {
- cmd_str = "dir /usr/tmp".to_string();
- }
-
- let output = if cfg!(target_os = "windows") {
- Command::new("cmd").arg("/c").arg(cmd_str).output().expect("cmd exec error!")
- } else {
- Command::new("sh").arg("-c").arg(cmd_str).output().expect("sh exec error!")
- }
-
- let output_str = String::from_utf8_lossy(&output.stdout);
- println!("{}", output_str);
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。