Rust 如何通过编译器选项重写常量?

Rust 如何通过编译器选项重写常量?,rust,Rust,是否可以在源代码中定义一个可以被编译器标志覆盖的常量?也就是说,类似于使用编译器的-D key=val选项在C预处理器中设置#define值 我已经通过#[cfg(…)]属性了解了条件编译,但这似乎只支持布尔值。我希望允许用户在编译期间设置常量的值 大概是这样的: #[from_cfg("max_dimensions")] const MAX_DIMENSIONS: usize = 100_000; 不,不能使用编译器标志定义常量(读取:constbindings)。但是你可以用这个来做类似的

是否可以在源代码中定义一个可以被编译器标志覆盖的常量?也就是说,类似于使用编译器的
-D key=val
选项在C预处理器中设置
#define

我已经通过
#[cfg(…)]
属性了解了条件编译,但这似乎只支持布尔值。我希望允许用户在编译期间设置常量的值

大概是这样的:

#[from_cfg("max_dimensions")]
const MAX_DIMENSIONS: usize = 100_000;

不,不能使用编译器标志定义常量(读取:
const
bindings)。但是你可以用这个来做类似的事情。它在编译时读取一些环境变量

遗憾的是,它返回的是字符串而不是整数。此外,我们还不能在编译时调用任意函数(如
parse
)来计算常量。您可以使用来实现类似的目标:

lazy_static! {
    static ref MAX_DIMENSIONS: usize = MAX_DIMENSIONS_RAW.parse().unwrap();
}
当然,您应该添加正确的错误处理。如果用户不需要定义环境变量,则可以使用

使用这种方法,您可以在构建时传递设置:

$ MAX_DIMENSIONS=1000 cargo build
在此基础上,您可以通过一些额外的间接方式将环境变量获取为常量,即使用

build.rs

use std::{env, fs::File, io::Write, path::Path};

fn main() {
    let out_dir = env::var("OUT_DIR").expect("No out dir");
    let dest_path = Path::new(&out_dir).join("constants.rs");
    let mut f = File::create(&dest_path).expect("Could not create file");

    let max_dimensions = option_env!("MAX_DIMENSIONS");
    let max_dimensions = max_dimensions
        .map_or(Ok(10_000), str::parse)
        .expect("Could not parse MAX_DIMENSIONS");

    write!(&mut f, "const MAX_DIMENSIONS: usize = {};", max_dimensions)
        .expect("Could not write file");
    println!("cargo:rerun-if-env-changed=MAX_DIMENSIONS");
}
include!(concat!(env!("OUT_DIR"), "/constants.rs"));

fn main() {
    println!("The value is {} ({})", MAX_DIMENSIONS, MAX_DIMENSIONS + 1);
}
main.rs

use std::{env, fs::File, io::Write, path::Path};

fn main() {
    let out_dir = env::var("OUT_DIR").expect("No out dir");
    let dest_path = Path::new(&out_dir).join("constants.rs");
    let mut f = File::create(&dest_path).expect("Could not create file");

    let max_dimensions = option_env!("MAX_DIMENSIONS");
    let max_dimensions = max_dimensions
        .map_or(Ok(10_000), str::parse)
        .expect("Could not parse MAX_DIMENSIONS");

    write!(&mut f, "const MAX_DIMENSIONS: usize = {};", max_dimensions)
        .expect("Could not write file");
    println!("cargo:rerun-if-env-changed=MAX_DIMENSIONS");
}
include!(concat!(env!("OUT_DIR"), "/constants.rs"));

fn main() {
    println!("The value is {} ({})", MAX_DIMENSIONS, MAX_DIMENSIONS + 1);
}
$cargo run
值为10000(10001)
$MAX_尺寸=17货物运行
该值为17(18)
$MAX_尺寸=1个货梯段
该值为1(2)

谢谢!我读过关于
env但不知何故错过了“编译时”部分:-)