常量和常量表达式

constant “常量”是一个与常量表达式值绑定的符号。常量表达式有限制,依赖于以下类别的值和运算,这些值和运算要么内置在语言中,要么在对常量表达式进行语义分析之前被声明和求值。

  • 字面值
  • 内置运算符
  • 先前声明的常量和编译期变量
  • 先前声明的宏和模板
  • 先前声明的过程,除了可能修改编译期变量外,没有任何副作用

常量表达式可以包含代码块,代码块可以是在编译期内支持的所有 Nim 特性(详见下面章节)。 在其代码块中,可以声明变量,随后读取和更新,或者声明变量并将其传递过程修改。 其代码块中的代码,仍须遵守上面列出的关于引用该代码块外的值和运算的限制。

访问和修改编译期变量的能力为常量表达式增加了灵活性,这可能会让了解其他静态类型语言的人感到惊讶。 例如,下面的代码在 编译期 返回斐波那契数列的起始部分。(这里只是对定义常量灵活性的演示,不是推荐的风格)。

  1. import std/strformat
  2. var fibN {.compileTime.}: int
  3. var fibPrev {.compileTime.}: int
  4. var fibPrevPrev {.compileTime.}: int
  5. proc nextFib(): int =
  6. result = if fibN < 2:
  7. fibN
  8. else:
  9. fibPrevPrev + fibPrev
  10. inc(fibN)
  11. fibPrevPrev = fibPrev
  12. fibPrev = result
  13. const f0 = nextFib()
  14. const f1 = nextFib()
  15. const displayFib = block:
  16. const f2 = nextFib()
  17. var result = fmt"Fibonacci sequence: {f0}, {f1}, {f2}"
  18. for i in 3..12:
  19. add(result, fmt", {nextFib()}")
  20. result
  21. static:
  22. echo displayFib