我试图在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),*);
}
}
问题是std::cmp::max
是一个函数,因此不能在常量表达式中使用(至少在const fn
稳定之前 - 我想尽可能保持稳定的Rust)。
如何在编译时计算一组常量的最大值?
我或许可以编写一个max!
宏,基本上可以递归地构建一个巨大的if
s链,但我希望那里有一个更清洁的解决方案。
虽然常量评估不支持if
或其他控制流,但有一种方法可以根据二进制条件选择值:
[a, b][(a < b) as usize]
这是做什么的
如果条件是usize
,则选择第一个元素,如果条件是false
,则选择第二个元素。
虽然这个方案理论上可以通过在多个铸造的true
s上通过数学运算计算索引来扩展到任意长度的数组,但只是去功能方式并嵌套上面的表达式似乎更简单:
bool
从Rust 1.31开始,const fn max(a: usize, b: usize) -> usize {
[a, b][(a < b) as usize]
}
const MAX: usize = max(max(max(5, 6), 42), 3);
可用于稳定的编译器。