Arrays
Arrays has a central role in programming. C3 offers build-in arrays, slices and vectors. The standard library enhances this further with dynamically sized arrays and other collections.
Fixed arrays
<type>[<size>]
e.g. int[4]
. These are treated as values and will be copied if given as parameter. Unlike C, the number is part of its type. Taking a pointer to a fixed array will create a pointer to a fixed array, e.g. int[4]*
.
Unlike C, fixed arrays do not decay into pointers, instead an int[4]*
may be implicitly converted into an int*
.
When you want to initialize a fixed array without specifying the size, use the [*] array syntax:
Slice
The final type is the slice <type>[]
e.g. int[]
. A slice is a view into either a fixed or variable array. Internally it is represented as a struct containing a pointer and a size. Both fixed and variable arrays may be converted into slices, and slices may be implicitly converted to pointers:
Slicing arrays
It’s possible to use a range syntax to create slices from pointers, arrays and other slicess. They either use range syntax:
arr[<start index>..<end index>]
(the end index is included in the final result) or start + len syntax: arr[<start index> : len]
It’s possible to omit the first and last index in ranges, and the start index for start + len. Omitting the start index will default it to 0, omitting the end index will set it to the last valid index (this is not allowed on pointers). Length cannot be omitted in start + len syntax.
The following are all equivalent:
One may also slice from the end. Again this is not allowed for pointers.
One may also use assign to slices:
Or copy slices to slices:
Copying overlapping ranges, e.g. a[1..2] = a[0..1]
is undefined behaviour.
Conversion list
int[4] | int[] | int[4]* | int* | |
---|---|---|---|---|
int[4] | copy | - | - | - |
int[] | - | assign | assign | - |
int[4]* | - | cast | assign | cast |
int* | - | assign | assign | assign |
Note that all casts above are inherently unsafe and will only work if the type cast is indeed compatible.
For example:
Internals
Internally the layout of a slice is guaranteed to be struct { <type>* ptr; usz len; }
.
There is a built-in struct std::core::runtime::SubArrayContainer
which has the exact data layout of the fat array pointers. It is defined to be
Iteration over arrays
You may iterate over slices, arrays and vectors using foreach (Type x : array)
:
Using &
it is possible to get an element by reference rather than by copy.
Furthermore, by providing two variable name, the first is assumed to be the
index:
It is possible to enable foreach on any type
by implementing “len” and ”[]” methods and annotating them using the @operator
attribute:
For more information, see operator overloading
Dynamic arrays and lists
The standard library offers dynamic arrays and other collections in the std::collections
module.