Arrays
A static array stores a fixed number of elements of the same type.
The size is written next to the element type: int[3] is an
array of three integers. The size can be any constant integer
expression, such as uint8[64 * 64 * 4].
void main() {
int[3] numbers = [1, 2, 3];
println(numbers[0]); // prints the first element, 1
println(numbers.size()); // prints 3
println(numbers[-1]); // prints the last element, 3
numbers[0] = 42;
println(numbers[0]); // prints 42
for number in numbers {
println(number);
}
}Out-of-bounds accesses are caught: constant indices are checked at compile time, and the index operator does bounds checks in debug builds.
A minus inside the brackets indexes from the end with no runtime
overhead: numbers[-1] is the last element and
numbers[-numbers.size()] is the first.
data() returns a pointer to the first element, for
passing the contents to C functions or doing pointer arithmetic:
void main() {
int[3] numbers = [1, 2, 3];
int[*] p = numbers.data();
println(p[0]); // prints 1
}Array literals must contain exactly as many elements as the declared
array size. A const array keeps its data view immutable, so
its data() result cannot be assigned to a mutable pointer
or used to mutate an element.
Arrays are values: assigning an array copies its elements. To pass an
array to a function without copying, take it by a slice view
(T[]), which refers to the caller's elements in place:
int sum(int[] numbers) {
var total = 0;
for number in numbers {
total += number;
}
return total;
}
void main() {
int[3] numbers = [1, 2, 3];
println(sum(numbers)); // prints 6
println(sum([4, 5])); // array literals work too, prints 9
}Array programming
Fixed-size arrays support element-wise arithmetic, like Odin:
float[3] can be used directly as a 3D vector, with no
wrapper struct needed. Both operands must have the same size; element
types must match exactly (use explicit conversions and float literals
for float arrays).
void main() {
float[3] a = [1.0, 2.0, 3.0];
float[3] b = [4.0, 5.0, 6.0];
float[3] c = a + b; // [5.0, 7.0, 9.0]
float[3] d = a * 2.0; // [2.0, 4.0, 6.0], scalar broadcasts
float[3] e = 10.0 - b; // [6.0, 5.0, 4.0], scalar on either side
println(c[0]); // prints 5
println(d[2]); // prints 6
println(e[0]); // prints 6
}Supported element-wise ops: + - * / % (and
%%), bitwise & | ^ << >> for
integer elements, and == != (which return
bool: == is true when all elements are equal,
!= when any differ).
void main() {
float[3] a = [1.0, 2.0, 3.0];
float[3] b = [1.0, 2.0, 3.0];
println(a == b); // prints true
println(a == [1.0, 2.0, 4.0]); // prints false
}Sizes must match; mismatched sizes are a compile error. Only arrays
of known (constant) size support element-wise ops; generic sizes
(T[N] with symbolic N) cannot unroll and are
rejected with a clear error.
Swizzles
Arrays of up to 4 numeric elements support GLSL-style swizzles: 1–4
characters from xyzw, rgba, or
stpq (one set per swizzle), mapping to indices 0–3
(x/r/s → 0,
y/g/t → 1,
z/b/p → 2,
w/a/q → 3). A single character
returns the element; multiple characters return a new array.
Out-of-bounds swizzles are compile errors. Swizzles are read-only for
now.
void main() {
float[3] v = [1.0, 2.0, 3.0];
println(v.x); // prints 1, same as v[0]
println(v.z); // prints 3
float[2] xy = v.xy; // [1.0, 2.0]
float[3] zyx = v.zyx; // [3.0, 2.0, 1.0]
float[2] rg = v.rg; // [1.0, 2.0], rgba set works too
println(xy[0]); // prints 1
println(zyx[0]); // prints 3
println(rg[1]); // prints 2
float[4] w = [1.0, 2.0, 3.0, 4.0];
println(w.w); // prints 4
float[2] ra = w.ra; // [1.0, 4.0]
println(ra[1]); // prints 4
}See List for a resizable array, and Pointers for array pointers and pointer arithmetic.