Var statement

Var statements declare new local and global variables and initialize them. A comma-separated list of variables can be used to specify variables of the same type:

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

If an initializer is given, the type can be omitted: the variable is then of the same type as the initializing expression. Variables are always initialized with a default value if there is no initializing expression. The default value depends on the type and is always a zero in binary.

Typedefault value
any integer type0
any float0.0
char‘\0’
boolfalse
ref or pointer typenil
procedural typenil
sequence@[]
string“”
tuple[x: A, y: B, …](zeroDefault(A), zeroDefault(B), …) (analogous for objects)
array[0…, T][zeroDefault(T), …]
range[T]default(T); this may be out of the valid range
T = enumcastT; this may be an invalid value

The implicit initialization can be avoided for optimization reasons with the noinit pragma:

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

If a proc is annotated with the noinit pragma, this refers to its implicit result variable:

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

The implicit initialization can also be prevented by the requiresInit type pragma. The compiler requires an explicit initialization for the object and all of its fields. However, it does a control flow analysis to prove the variable has been initialized and does not rely on syntactic properties:

  1. type
  2. MyObject {.requiresInit.} = object
  3. proc p() =
  4. # the following is valid:
  5. var x: MyObject
  6. if someCondition():
  7. x = a()
  8. else:
  9. x = a()
  10. # use x

requiresInit pragma can also be applied to distinct types.

Given the following distinct type definitions:

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

The following code blocks will fail to compile:

  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"

But these will compile successfully:

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