我正在尝试在Rust程序宏(派生宏)内的编译时计算一组常量的最大值。
宏看起来像:
fn get_max_len() -> TokenStream {
// Each TokenStream represents a constant expression
let len: Vec<TokenStream> = get_constant_lengths();
quote! {
// #(#len),* gets expanded to #len[0], #len[1], #len[2]...
const LEN: usize = std::cmp::max(#(#len),*);
}
}
Run Code Online (Sandbox Code Playgroud)
问题是这std::cmp::max是一个函数,因此不能在常量表达式内使用(至少直到const fn稳定为止-如果可能的话,我想保持Rust稳定)。
如何在编译时计算一组常量的最大值?
我也许可以编写一个max!宏,该宏基本上以if递归方式构造一个庞大的s 链,但是我希望那里有一个更干净的解决方案。
尽管不支持常量评估if或其他控制流程,但是有一种方法可以根据二进制条件选择值:
[a, b][(a < b) as usize]
Run Code Online (Sandbox Code Playgroud)
这是什么
usize如果条件为false,则选择第一个元素,如果条件为,则选择第二个元素true。
尽管该方案理论上可以通过对多个强制转换的bools 进行数学运算来计算索引,从而扩展到任意长度的数组,但仅采用函数方式并嵌套上面的表达式似乎更简单:
const fn max(a: usize, b: usize) -> usize {
[a, b][(a < b) as usize]
}
const MAX: usize = max(max(max(5, 6), 42), 3);
Run Code Online (Sandbox Code Playgroud)
从Rust 1.31开始,const fn可在稳定的编译器上使用。