Variables

name := 'Bob' age := 20 large_number := i64(9999999999) println(name) println(age) println(large_number)

Variables are declared and initialized with :=. This is the only way to declare variables in V. This means that variables always have an initial value.

The variable's type is inferred from the value on the right hand side. To choose a different type, use type conversion: the expression T(v) converts the value v to the type T.

Unlike most other languages, V only allows defining variables in functions. By default V does not allow global variables. See more details.

For consistency across different code bases, all variable and function names must use the snake_case style, as opposed to type names, which must use PascalCase.

Mutable variables

mut age := 20 println(age) age = 21 println(age)

To change the value of the variable use =. In V, variables are immutable by default. To be able to change the value of the variable, you have to declare it with mut.

Try compiling the program above after removing mut from the first line.

Initialization vs assignment

Note the (important) difference between := and =. := is used for declaring and initializing, = is used for assigning.

fn main() { age = 21 }

This code will not compile, because the variable age is not declared. All variables need to be declared in V.

fn main() { age := 21 }

The values of multiple variables can be changed in one line. In this way, their values can be swapped without an intermediary variable.

mut a := 0 mut b := 1 println('${a}, ${b}') // 0, 1 a, b = b, a println('${a}, ${b}') // 1, 0

Warnings and declaration errors

In development mode the compiler will warn you that you haven't used the variable (you'll get an "unused variable" warning). In production mode (enabled by passing the -prod flag to v – v -prod foo.v) it will not compile at all (like in Go).

fn main() { a := 10 // warning: unused variable `a` }

To ignore values returned by a function _ can be used

fn foo() (int, int) { return 2, 3 } fn main() { c, _ := foo() print(c) // no warning about unused variable returned by foo. }

Unlike most languages, variable shadowing is not allowed. Declaring a variable with a name that is already used in a parent scope will cause a compilation error.

fn main() { a := 10 if true { a := 20 // error: redefinition of `a` } }

While variable shadowing is not allowed, field shadowing is allowed.

pub struct Dimension { width int = -1 height int = -1 } pub struct Test { Dimension width int = 100 // height int } fn main() { test := Test{} println('${test.width} ${test.height} ${test.Dimension.width}') // 100 -1 -1 }