rust 支持compile time的feature toggle,可以在 Cargo.toml
中指定feature
[package]
name = "feature_toggle"
version = "0.1.0"
authors = ["Sean <xujihui1985@gmail.com>"]
edition = "2018"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]
[features]
benchmarking = []
mutate_state = ["lazy_static"]
enable_traceing = []
enable_retry = []
key代表feature的名字,后面的[] 代表这个feature依赖的crate,例如 mutate_state 这个feature依赖 lazy_static,那么在打开这个feature后,cargo就会将lazy_static编译进来
通过annotation
fn do_sth() {
println!("we do sth nornmal here");
#[cfg(feature="benchmarking")]
{
println!("benchmarking");
println!("we do sth inside benchmarking");
}
println!("we do sth after benchmarking");
}
fn main() {
do_sth();
}
根据feature不同的实现
#[derive(Debug)]
struct MyStruct {
name: String,
}
#[cfg(feature="mutate_state")]
fn mutate_slice(s: &mut [MyStruct]) {
println!("mutate_state");
for i in s.iter_mut() {
i.name = String::from("ddddd");
}
}
#[cfg(not(feature="mutate_state"))]
fn mutate_slice(s: &mut [MyStruct]) {
println!("do not mutate state");
for i in s {
println!("{:?}", i);
}
}
fn main() {
let mut s = vec![
MyStruct{name: String::from("aaa")},
MyStruct{name: String::from("bbb")},
MyStruct{name: String::from("ccccc")},
];
mutate_slice(&mut s);
for i in s.into_iter() {
println!("after mutate {:?}", i);
}
}
compile time if expression
fn complie_time_flag() {
if cfg!(feature="enable_traceing") {
println!("starting");
}
println!("in the body of complie_time_flag");
}
compile time const
#[cfg(feature="enable_retry")]
const MAX_RETRY:u32 = 3;
#[cfg(not(feature="enable_retry"))]
const MAX_RETRY:u32 = 0;
fn main() {
if cfg!(feature="enable_retry") {
println!("retry time {}", MAX_RETRY);
}
}
build/run with feature
cargo run --features "mutate_state","enable_traceing","enable_retry"