仓库源文站点原文

上文,尝试了解 cfg 和 not 的语义。

cfg

中文化例程:

// This function only gets compiled if the target OS is linux
#[cfg(target_os = "linux")]
fn 在跑linux() {
    println!("你在跑linux!");
}

// And this function only gets compiled if the target OS is *not* linux
#[cfg(not(target_os = "linux"))]
fn 在跑linux() {
    println!("你昧在跑linux!");
}

fn main() {
    在跑linux();

    println!("确定?");
    if cfg!(target_os = "linux") {
        println!("是。的确!");
    } else {
        println!("是。不是!");
    }
}

输出:

你在跑linux!
确定?
是。的确!

试了win下,输出照样是 linux。

的确,是运行代码的远端服务器的系统而非本地。

为确认有否编译,将第一段的 println! 去掉了 !,报错如下:

error[E0423]: expected function, found macro `println`
 --> src/main.rs:4:5
  |
4 |     println("你在跑linux!");
  |     ^^^^^^^ not a function
  |
help: use `!` to invoke the macro
  |
4 |     println!("你在跑linux!");
  |            +

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

而将第二段的 println!("你昧在跑linux!"); 去掉 ! 后,编译无误,输出同开始,果然昧编译。

在标识符命名风格方面,原例程似乎用了下划线分隔如 are_you_on_linux target_os,看来至少此教程采用了 可读性更好的方式,不知是否为 Rust 普遍建议的风格。

not

用 not 没 搜到,在线文档有待改进。

粗翻了一遍 整篇教程,只看到 ==,没看到 !=,用两者搜也搜不出页面。

如把判断条件改为 target_os != "linux" 报错如下:

error: expected 1 cfg-pattern
  --> src/main.rs:17:8
   |
17 |     if cfg!(target_os != "linux") {
   |        ^^^^^^^^^^^^^^^^^^^^^^^^^^
   |
   = note: this error originates in the macro `cfg` (in Nightly builds, run with -Z macro-backtrace for more info)

error: could not compile `playground` (bin "playground") due to 1 previous error

第一次注意到反馈内容中的‘无法编译’。

改成 cfg!(not(target_os = "linux")) 就如期运行了,的确如教程所言(Both utilize identical argument syntax),#[cfg(...)]cfg!(...) 的参数结构相同。

猜度 not() 可作为一般布尔表达式的取否,先写了个简单条件语句:

fn main() {
    if (2<1) {
        println!("没错");
    } else {
        println!("错了!");
    }
}

报警说条件的括号不需要:

warning: unnecessary parentheses around `if` condition
  --> src/main.rs:14:8
   |
14 |     if (2<1) {
   |        ^   ^
   |
   = note: `#[warn(unused_parens)]` on by default
help: remove these parentheses

输出:错了!

尝试加了个 not,结果报错:

error[E0425]: cannot find function `not` in this scope
  --> src/main.rs:14:8
   |
14 |     if not(2<1) {
   |        ^^^ not found in this scope
   |
help: consider importing one of these functions
   |
2  + use nom::combinator::not;
   |
2  + use winnow::combinator::not;
   |

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

改成 not! 也类似报错。看来not并非通用,难道仅用于 #[cfg]?如果这样感觉有点浪费了 not 这么常用的关键词。

待研究。