是否可以在源代码中定义一个可以被编译器标志覆盖的常量?也就是说,类似#define在C预处理器中设置带有-D key=val编译器选项的值。
我已经阅读了有关通过#[cfg(...)]属性进行条件编译的信息,但这似乎仅支持布尔值。我想允许用户在编译期间设置常量的值。
像这样:
#[from_cfg("max_dimensions")]
const MAX_DIMENSIONS: usize = 100_000;
Run Code Online (Sandbox Code Playgroud)
不,您不能const使用编译器标志定义常量(读取:绑定)。但是您可以将env!宏用于类似的东西。它在编译时读取一些环境变量。
const MAX_DIMENSIONS_RAW: &'static str = env!("MAX_DIMENSIONS");
Run Code Online (Sandbox Code Playgroud)
可悲的是,这将返回字符串而不是整数。此外,我们还不能parse在编译时调用任意函数(如)来计算常量。您可以lazy_static用来实现类似的目的:
lazy_static! {
static ref MAX_DIMENSIONS: usize = MAX_DIMENSIONS_RAW.parse().unwrap();
}
Run Code Online (Sandbox Code Playgroud)
当然,您应该添加适当的错误处理。如果您的用户不需要定义环境变量,则可以使用option_env!。
使用这种方法,您可以在构建时通过设置:
$ MAX_DIMENSIONS=1000 cargo build
Run Code Online (Sandbox Code Playgroud)
在Lukas Kalbertodt的答案的基础上,您可以通过一些额外的间接方式(即通过使用构建脚本)将环境变量获取为常数。
构建器
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");
}
Run Code Online (Sandbox Code Playgroud)
主
include!(concat!(env!("OUT_DIR"), "/constants.rs"));
fn main() {
println!("The value is {} ({})", MAX_DIMENSIONS, MAX_DIMENSIONS + 1);
}
Run Code Online (Sandbox Code Playgroud)
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");
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
428 次 |
| 最近记录: |