Slices and Pointers
A slice's header exposes its data pointer and length directly, which is what makes low-level and foreign-code access possible without copying. An array exposes the same two fields, so everything here applies to both.
Reaching the Backing Memory
A slice's data field is a regular *T pointer. You can pass it to extern functions or perform pointer arithmetic on it when low-level access is needed:
extern func memcpy(dst: *opaque, src: *opaque, n: uint) -> *opaque;
let src = [1, 2, 3, 4]; // int[4]
var dst: Slice<int> = allocate(4); // a slice over four ints
let bytes = sizeof(int) * src.length;
memcpy(dst.data, src.data, bytes); // dst now holds 1, 2, 3, 4
Passing data hands the callee the address of the first element; passing a byte count derived from length tells it how far the region extends. The two are always used together — a pointer without its length cannot be bounded safely.
sizeof and Element Size
length counts elements, not bytes. sizeof(T) returns the size of a single element in bytes, so multiplying the two gives the total byte size of the backing region — exactly what a C API that works in bytes expects:
let buf: float64[4] = [1.0, 2.0, 3.0, 4.0];
let byteSize = sizeof(float64) * buf.length; // 32
See Also
- Slices — the slice view type and its memory layout
- Pointer Arithmetic — advancing a pointer by element size
- Pointers and
extern— exchanging memory with native code
Indexing and Iteration
A slice reaches its elements exactly as an array does — by position or in a loop — because both share the same element access. What is unique to a slice is that the access goes through its data pointer into memory it does not own.
Overview
A range describes an interval between two bounds. It is written with the .. and ..= operators and used mainly to drive a for loop or to take a sub-slice of an array. A range is an ordinary value — it can be stored in a variable and its bounds read back.