常量求值

常量求值是在编译期间计算表达式结果的过程。只有一部分表达式可以在编译时求值。

常量表达式

某些形式的表达式,称为常量表达式,可以在编译时求值。在常量上下文中,这些是唯一允许的表达式,并且总是在编译时求值。在其他地方,例如let 语句中,常量表达式*可能*在编译时求值,但不能保证。如果值必须在编译时求值(即在常量上下文中),则诸如越界数组索引溢出之类的行为是编译器错误。否则,这些行为是警告,但很可能在运行时出现恐慌。

以下表达式是常量表达式,只要任何操作数也是常量表达式并且不会导致运行任何Drop::drop调用。

常量上下文

*常量上下文*是以下情况之一

常量函数

*常量函数 (const fn)* 是允许从常量上下文调用的函数。将函数声明为 const 对任何现有用法都没有影响,它只会限制参数和返回类型可以使用的类型,以及防止在其中使用各种表达式。您可以自由地对常量函数执行与常规函数相同的操作。

当从常量上下文调用时,编译器会在编译时解释该函数。解释发生在编译目标的环境中,而不是主机环境中。因此,如果您针对 32 位系统进行编译,则 usize32 位,而与您是在 64 位还是 32 位系统上构建无关。

常量函数有各种限制,以确保它们可以在编译时求值。例如,不可能将随机数生成器编写为常量函数。在编译时调用常量函数将始终产生与在运行时调用它相同的结果,即使多次调用也是如此。此规则有一个例外:如果您在极端情况下执行复杂的浮点运算,则可能会得到(略微)不同的结果。建议不要使数组长度和枚举判别式依赖于浮点计算。

在常量上下文中允许但在常量函数中不允许的值得注意的功能包括

  • 浮点运算
    • 浮点值被视为泛型参数,除了 Copy 之外没有特征边界。所以你不能对它们做任何事情,只能复制/移动它们。

相反,以下内容在常量函数中是可能的,但在常量上下文中是不可能的

  • 使用泛型类型和生命周期参数。