函数参数的Rust特性标志



是否有办法将Rust的特性标志支持应用于函数参数?我有一个函数,它接受一堆输入,但其中一个输入应该只在一个特征是活动的情况下传递。当然我也可以把这个参数设为可选的,比如:

pub fn my_function(input1: usize, input2: String, input3: Option<Vec<u32>>) -> () {...}

但是是否有一种方法可以代替使用功能标志并定义这样的东西?:

pub fn my_function(
input1: usize,
input2: String,
#[cfg(feature = "my-feature")]
input3: Vec<u32>
) -> () {...}

类似地,后来称之为:my_function(0, "", #[cfg(feature = "my-feature")] vec![0])?

Rust的特性标志是对条件编译的一个薄包装。想象一下,如果始终启用该特性,那么您将如何编写代码,然后如果始终禁用该特性,并将两者之间的行用#[cfg(..])表达式换行。要定义一个不同的函数,你可以定义两个不同的版本,如果它们几乎相同,让它们调用一个共享的内部块,或者如果它们应该做不同的事情,就单独定义它们:

struct Thing;
impl Thing {
#[cfg(not(feature = "my-feature"))]
pub fn my_function(input1: usize, input2: String) {
Thing::my_function_inner(input1, input2, None);
}
#[cfg(feature = "my-feature")]
pub fn my_function(input1: usize, input2: String, input3: Vec<u32>) {
Thing::my_function_inner(input1, input2, Some(input3));
}
#[inline]
fn my_function_inner(input1: usize, input2: String, input3: Option<Vec<u32>>) {
todo!();
}
}

或者,您可以简单地用cfg表达式标记条件参数,并在函数体内使用条件编译:

impl Thing {
pub fn my_function(
input1: usize,
input2: String,
#[cfg(feature = "my-feature")] input3: Vec<u32>,
) {
// common implementation
#[cfg(feature = "my-feature")]
{ /* `input3` is only available when feature is enabled */ }
#[cfg(not(feature = "my-feature"))]
{ /* only run when feature is disabled */ }
}
}

选择对您的用例最有意义的。编译器可能会对它们进行类似的优化。

要调用它,你可以依赖于始终处于启用/禁用状态的特性标志,并只使用相应的版本,或者你可以像这样包含两者的代码:

fn main() {
#[cfg(not(feature = "my-feature"))]
Thing::my_function(0, "".to_string());
#[cfg(feature = "my-feature")]
Thing::my_function(0, "".to_string(), vec![0]);
}

编辑:为了支持有条件编译的返回类型,您可以将返回类型声明为type别名,该别名本身是有条件编译的,如下所示:

#[cfg(feature = "my-feature")]
type ReturnType = (usize, usize);
#[cfg(not(feature = "my-feature"))]
type ReturnType = (usize,);
fn my_function() -> ReturnType { todo!() }

感谢@ChayimFriedman和@Jmb。

最新更新