Var语句

Var 语句声明新的局部和全局变量并初始化它们。逗号分隔的变量列表可用于指定相同类型的变量:

  1. var
  2. a: int = 0
  3. x, y, z: int

如果给定了初始化器,则可以省略类型: 变量的类型与初始化表达式的类型相同。如果没有初始化表达式,则始终使用默认值初始化变量。默认值取决于类型,并且在二进制中始终为零。

类型默认值
任意整数0
任意浮点数0.0
字符‘\0’
布尔false
引用和指针nil
过程nil
序列@[]
字符串“”
tuple[x: A, y: B, …](zeroDefault(A), zeroDefault(B), …) (analogous for objects)
array[0…, T][zeroDefault(T), …]
range[T]default(T); 这个有可能超出有效范围
T = enumcastT; 这个有可是无效值

出于优化原因,可以使用 noinit “无初始化”编译指示来避免隐式初始化:

  1. var
  2. a {.noinit.}: array[0..1023, char]

如果 proc 使用 noinit 编译指示,这指的是其隐式 result 变量:

  1. proc returnUndefinedValue: int {.noinit.} = discard

requiresInit “需初始化”类型编译指示也可以防止隐式初始化。 编译器需要对对象及其所有字段进行显式初始化。 但是,它会进行 control flow analysis “控制流分析” 以验证变量已被初始化并且不依赖于语法属性:

  1. type
  2. MyObject {.requiresInit.} = object
  3. proc p() =
  4. # 以下是有效的:
  5. var x: MyObject
  6. if someCondition():
  7. x = a()
  8. else:
  9. x = a()
  10. # 使用 x

requiresInit 编译指示也可以应用于 distinct 类型。

给出以下 distinct 类型定义:

  1. type
  2. Foo = object
  3. x: string
  4. DistinctFoo {.requiresInit, borrow: `.`.} = distinct Foo
  5. DistinctString {.requiresInit.} = distinct string

下列代码块将会编译失败:

  1. var foo: DistinctFoo
  2. foo.x = "test"
  3. doAssert foo.x == "test"
  1. var s: DistinctString
  2. s = "test"
  3. doAssert string(s) == "test"

但这些将会编译成功:

  1. let foo = DistinctFoo(Foo(x: "test"))
  2. doAssert foo.x == "test"
  1. let s = DistinctString("test")
  2. doAssert string(s) == "test"