Values and variables
Bindings introduce named values. val is immutable, var is mutable, and both require an explicit type - mach has no type inference.
Declaring bindings
A binding names a value with a declared type. val is constant once set; var can be reassigned. Every form pins the type in the declaration.
val NAME: TYPE = EXPR; # immutable; initializer required
var NAME: TYPE; # mutable; default-initialized
var NAME: TYPE = EXPR; # mutable; explicit initializer
Mutability and defaults
A val always carries an initializer and cannot be reassigned. A var may omit its initializer, in which case it is default-initialized (zeroed), and it can be written to afterward.
val pi: f64 = 3.14159;
val n: i64 = 42;
var counter: i64 = 0;
var buf: [256]u8; # default-initialized to zero
counter = counter + 1; # var is reassignable
Scope and exports
Both forms work at module top level and inside function bodies. Inside a function, a binding is local to its enclosing block. At module top level, pub exports it:
pub val NAMEexports the constant.pub var NAMEexports the variable as a writable global.
No type inference
Every binding declares its type. An untyped numeric literal is checked against the binding's declared type; it never participates in inferring that type.
val n: i64 = 42; # ok - 42 conforms to i64
val x = 42; # ERROR - no type to check against
When the surrounding context does not constrain a literal's type, give it a typed suffix such as 42i64.
See also
- Types - the type grammar used in the annotation
- Visibility - how
pubexports bindings - Functions - parameters and return values