Arrays
Arrays are dynamic, homogeneous reference values. Append [] to an element
type and initialize the variable with an array literal:
int[] values = [1, 2, 3]
str[] names = []
int[][] matrix = [[1, 2], [3, 4]]An empty literal needs a type context, such as a variable declaration, function argument, or return value. A standalone empty literal is rejected because its element type cannot be inferred. A trailing comma is allowed.
Use len to read the current length, push to append, and brackets to read or
replace an element:
values.push(5)
values[0] = 8
values[1] += 10
print(values.len(), values[0])Each built-in that takes an array, a string, bytes, or a map first, and
each function of the prelude, as map, filter, and sort, is also a
method of it: values.push(5) is push(values, 5), and
text.split(",").join(" ") is join(split(text, ","), " "). Both are
written in this reference, and a type's own method of the same name, as
one declared with func str[].push(self, ...), comes first.
pop(values) removes and returns the last element. Popping an empty array
terminates the program with a runtime error. These built-ins work on arrays
too:
| Built-in | Result | Behavior |
|---|---|---|
insert(a, index, value) |
none | puts value at index, from 0 to len(a), moving later elements up |
remove_at(a, index) |
element | removes the element at index and returns it |
reverse(a) |
none | reverses the order of the elements in place |
slice(a, start, end) |
array | a new array with the elements from start up to end |
view(a, start, end) |
array | the elements from start up to end, shared with a rather than copied |
reserve(a, count) |
none | makes room for count more elements, so adding them does not grow the array again |
push_bytes(a, data) |
none | adds the values of bytes data to the end of a u8[] |
find(a, value) |
i64 |
the index of the first element equal to value, or -1 |
a + b |
array | a new array with the elements of a, then those of b |
view makes an array of part of another without copying it: an element
written through either is written in both, and a view keeps showing its
array's elements after the array grows. Its length cannot change, so push,
pop, insert, and remove_at on a view are runtime errors, and using a
view whose array has become shorter than it is one too. Operations that work
in place, such as sort and reverse, change just the view's elements:
int[] scores = [7, 3, 9, 1, 8]
sort(view(scores, 0, 3)) // scores is now [3, 7, 9, 1, 8]
int[] best = view(scores, 2, 5)
best[0] = 10 // scores[2] is now 10A view of a view shows the same array, and a view of a constant's array
cannot change it either. slice gives an array of its own instead.
find and in work for the element types that maps accept as keys. Sorting,
map, filter, and the other operations that take a function are described
under functions as values.
Arrays remain shared when passed to or returned from functions, so push and
indexed assignment inside a function affect the same array. Indexes must be
integers. Negative and out-of-range indexes terminate the program with a
Cuarzo runtime error instead of reading invalid memory.
The garbage collector reclaims an array once nothing refers to it, so there is no explicit deletion.