一、条件编译
条件编译其实是从名字就可以知道意思,通过控制预设的编译条件来通知编译器按照指定的条件来编译当前程序。注意,它是一种静态编译的手段。学过c/c++的应该都非常清楚。条件编译一般在语言中会有条件编译指令。比如在c++中有#ifdef等等。条件编译一般都不会特别复杂,可以理解成一个编译器的编译开关即可。
二、Rust中对条件编译的支持
在Rust中,同样支持条件编译。它使用的其实是上节中的属性来实现条件编译的,主要是cfg这个配置属性。其实常见的编译条件就是不同的平台和不现的发布版本。比如Windows平台和Linux平台或者Max平台,是Release版本还是Debug版本,都可以通过配置属性来实现这个目的。
看一下例子:
#[cfg(target_os = "macos")]
fn cross_platform() {
// Will only be compiled on Mac OS, including Mac OS X
}
#[cfg(target_os = "windows")]
fn cross_platform() {
// Will only be compiled on Windows
}
// 若条件`foo`或`bar`任意一个成立,则编译以下的Item
#[cfg(any(foo, bar))]
fn need_foo_or_bar() {
}
// 针对32位的Unix系统
#[cfg(all(unix, target_pointer_width = "32"))]
fn on_32bit_unix() {
}
// 若`foo`不成立时编译
#[cfg(not(foo))]
fn needs_not_foo() {
}
三、条件编译的具体说明
Rust中的cfg配置条件有:
1、debug_assertions
调试版本的判断。
2、target_arch = “…”
目标平台的CPU架构,包括但不限于x86, x86_64, mips, powerpc, arm或aarch64。
3、target_endian = “…”
目标平台的大小端即大端模式(big)和小端模式(little)。
4、target_env = “…”
应用的运行库,比如musl表示使用的是MUSL的libc实现, msvc表示使用微软的MSVC,gnu表示使用GNU的实现。但在部分平台这个数据是空的。
5、target_family = “…”
表示目标操作系统的类别,比如windows和unix。这个属性可以直接作为条件使用,如#[unix],#[cfg(unix)]。
6、target_os = “…”
目标操作系统,包括但不限于windows, macos, ios, linux, android, freebsd, dragonfly, bitrig, openbsd, netbsd。
7、target_pointer_width = “…”
目标平台的指针宽度,一般就是32或64。
8、target_vendor = “…”
生产商,例如apple, pc或大多数Linux系统的unknown。
9、test
当启动了单元测试时(即编译时加了–test参数,或使用cargo test)。
在Rust中,可能通过使用cfg_attr以一个条件去设置另一个条件:
#[cfg_attr(a, b)]
这表示若a成立,则这个就相当于#[cfg(b)]。
这个cfg的属性只能应用于Item,对于非Item项,可以使用cfg!宏来实现:
if cfg!(target_arch = "x86") {
} else if cfg!(target_arch = "x86_64") {
} else if cfg!(target_arch = "mips") {
} else {
}
这个条件编译一般应用场合还是比较固定的,所以对这个可能即使小白也可以很快的适应出来,这才是根本,简单就是王道。还是要多说一句,计算机编程,实践是第一要务,多学习,多实践!
四、总结
有针对性对不同的语言的类似的功能进行对比和总结,就能够更加深刻的理解既有的知识和新语言的知识。通过对比,既能知道原有的为什么这样做,又可以理解新语言为什么要改进一些东西。正如谚语上说得好:上帝为你打开一扇窗子,就会对你关闭一扇门。所有的东西其实就是选择,妄想着一切都是美好的想法,做梦估计都做不出来。