static[T]

如名称所示,静态参数必须是常数表达式:

  1. proc precompiledRegex(pattern: static string): RegEx =
  2. var res {.global.} = re(pattern)
  3. return res
  4. precompiledRegex("/d+") # 这个调用被替换成一个预编译的、
  5. # 存储在全局变量里的正则表达式
  6. precompiledRegex(paramStr(1)) # 错误,命令行选项不是常数表达式

出于代码生成的目的,所有静态参数都被视为泛型参数,即过程将为每个特定值提供(或值的组合)单独编译。

静态参数也可以出现在泛型类型签名中:

  1. type
  2. Matrix[M,N: static int; T: Number] = array[0..(M*N - 1), T]
  3. # 注意这里的 `Number` 只是一个类型约束,而
  4. # `static int` 则要求我们提供一个整数值
  5. AffineTransform2D[T] = Matrix[3, 3, T]
  6. AffineTransform3D[T] = Matrix[4, 4, T]
  7. var m1: AffineTransform3D[float] # OK
  8. var m2: AffineTransform2D[string] # 错误,`string` 不是一种 `Number`

请注意, static T 只是底层泛型 static[T] 的语法便利。 类型参数可以被省略,以获得所有常量表达式的类型类。通过将 static 与另一个类型类实例化,来创建更具体的类型类。

把表达式强制转换成对应的 static 类型可以强制其像常数表达式一样在编译期就进行求值。

  1. import std/math
  2. echo static(fac(5)), " ", static[bool](16.isPowerOfTwo)

编译器将报告表达式求值失败或可能的类型不匹配错误。