Variables & Bindings
Let Bindings
Variables are introduced with let. They are immutable by default.
let x = 5
let name = "Alice"
Optional type annotation:
let x: i64 = 5
Bindings can use any expression:
let x = 5 + 3
let y = x * 2
let result = compute(42)
let s = "hello".to_upper()
Destructuring
Tuples:
let (a, b) = get_pair()
let (a, (b, c)) = get_nested()
let (_, b) = get_pair() // wildcard discards first element
Structs:
let Point { x, y } = get_point()
let Point { x: px, y: py } = get_point() // rename fields
let Config { name, .. } = get_config() // ignore remaining fields
Rebinding
The = operator rebinds a name to a new value. This is shadowing, not mutation:
fn count() -> i64:
let x = 0
x = x + 1 // x is now 1 (new binding, not mutation)
x = x + 2
x // 3
Compound assignment operators desugar to rebinding (see Operators):
fn count() -> i64:
let x = 0
x += 1
x += 2
x // 3
Field rebinding:
let p = Point::new(1, 2)
p.x = 10 // creates new binding with updated field
Constants
Top-level compile-time values with required type annotations:
const MAX_SIZE: i64 = 1024
const PI: f64 = 3.14159
const GREETING: String = "hello"
const YES: bool = true
const BYTE_A: u8 = 'a'
Constants support all literal forms:
const HEX: i64 = 0xFF
const BIN: i64 = 0b1010
const OCT: i64 = 0o77
const SCI: f64 = 1.5e10
const TRIPLE: String = """triple quoted"""
Visibility and attributes:
pvt const SECRET: i64 = 42
#[deprecated]
const OLD_VALUE: i64 = 0