是否有可能在Rust的编译时计算递归函数?

问题描述 投票:5回答:1

我想计算const的阶乘。我想最终得到这样的东西:

const N: usize = 4;
const N_PERMUTATIONS = factorial(N);

显而易见的解决方案(不起作用)是:

  • const fn - 在const fn中不允许(或至少没有实现)条件语句,以下都不会编译: const fn factorial(n: usize) -> usize { match n { 0 => 1, _ => n * factorial(n-1) } } const fn factorial(n: usize) -> usize { if n == 0 { 1 } else { n * factorial(n-1) } }
  • 宏 - 在所有宏扩展之后执行表达式的评估。这个宏永远不会达到基本情况,因为在四次迭代之后,参数是4-1-1-1-1,它与0不匹配: macro_rules!factorial { (0) => (1); ($n:expr) => ($n * factorial($n-1)); }

我也尝试了以下,如果*有短路评估,这将有效,但as-is有无条件的递归,产生堆栈溢出:

const fn factorial(n: usize) -> usize {
    ((n == 0) as usize) + ((n != 0) as usize) * n * factorial(n-1)
}

(正如Matthieu M.指出的那样,我们可以通过使用factorial(n - ((n != 0) as usize))来避免下溢。)

现在我已经使用手动计算阶乘。

recursion macros rust const compile-time-constant
1个回答
3
投票

目前在const_fn功能下进行了探索,但是现在你无法从另一个const函数调用函数,甚至是const。

然而,你可以打破大枪:元编程(程序宏)来计算编译时的值。我发现this crate例如(但是没有测试它)。

This Rosetta Code page on compile time calculation表明编译器可以进行一些编译时优化,但没有任何保证,这只是一个特例。

© www.soinside.com 2019 - 2024. All rights reserved.