常量求值

常量求值是在编译期间计算 表达式 结果的过程。 其条件是所有表达式的子集能够在编译时进行求值。

常量表达式

常量表达式可以在编译时求值。在 常量上下文 中,唯一允许的表达式,并且始终在编译时求值。 在其他位置,如 let 语句 中,常量表达式可能会被求值,但不能保证在编译时求值。 如果必须在编译时求值 (即在常量上下文中) ,则越界的 数组索引溢出 等行为会导致编译器错误。 否则,这些行为会导致警告,但可能会在运行时崩溃。

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

常量上下文

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

常量函数

常量函数是指允许在常量上下文中调用的函数。 将函数声明为 const 不会影响函数现有的用途,只限制了参数和返回类型可以使用的类型和表达式。 可以像普通函数一样自由地使用常量函数进行相同的操作。

在常量上下文中调用函数时,编译器会在编译时解释该函数。解释环境为编译目标,而不是主机环境。 因此,如果你正在针对 32 位系统进行编译,则无论是在 64 位系统还是 32 位系统上构建, usize 都是 32 位。

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

允许在常量上下文中使用但不允许在常量函数中使用的显著特性包括:

  • 浮点运算
    • 浮点值与除了 Copy 之外的 trait 约束的泛型参数一样处理。因此,你无法对它们进行任何操作,只能复制/移动它们。

在常量函数中可以使用以下内容,但在常量上下文中不行:

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