2024-04-25 01:41:47 +01:00
|
|
|
const expect = @import("std").testing.expect;
|
2024-05-07 19:00:42 +01:00
|
|
|
const expectEqualSlices = @import("std").testing.expectEqualSlices;
|
2024-04-25 01:41:47 +01:00
|
|
|
|
|
|
|
test "basic slices" {
|
|
|
|
var array = [_]i32{ 1, 2, 3, 4 };
|
|
|
|
var known_at_runtime_zero: usize = 0;
|
|
|
|
_ = &known_at_runtime_zero;
|
|
|
|
const slice = array[known_at_runtime_zero..array.len];
|
2024-05-07 19:00:42 +01:00
|
|
|
|
|
|
|
// alternative initialization using result location
|
|
|
|
const alt_slice: []const i32 = &.{ 1, 2, 3, 4 };
|
|
|
|
|
|
|
|
try expectEqualSlices(i32, slice, alt_slice);
|
|
|
|
|
2024-04-25 01:41:47 +01:00
|
|
|
try expect(@TypeOf(slice) == []i32);
|
|
|
|
try expect(&slice[0] == &array[0]);
|
|
|
|
try expect(slice.len == array.len);
|
|
|
|
|
|
|
|
// If you slice with comptime-known start and end positions, the result is
|
|
|
|
// a pointer to an array, rather than a slice.
|
|
|
|
const array_ptr = array[0..array.len];
|
|
|
|
try expect(@TypeOf(array_ptr) == *[array.len]i32);
|
|
|
|
|
|
|
|
// You can perform a slice-by-length by slicing twice. This allows the compiler
|
|
|
|
// to perform some optimisations like recognising a comptime-known length when
|
|
|
|
// the start position is only known at runtime.
|
|
|
|
var runtime_start: usize = 1;
|
|
|
|
_ = &runtime_start;
|
|
|
|
const length = 2;
|
|
|
|
const array_ptr_len = array[runtime_start..][0..length];
|
|
|
|
try expect(@TypeOf(array_ptr_len) == *[length]i32);
|
|
|
|
|
|
|
|
// Using the address-of operator on a slice gives a single-item pointer.
|
|
|
|
try expect(@TypeOf(&slice[0]) == *i32);
|
|
|
|
// Using the `ptr` field gives a many-item pointer.
|
|
|
|
try expect(@TypeOf(slice.ptr) == [*]i32);
|
|
|
|
try expect(@intFromPtr(slice.ptr) == @intFromPtr(&slice[0]));
|
|
|
|
|
|
|
|
// Slices have array bounds checking. If you try to access something out
|
|
|
|
// of bounds, you'll get a safety check failure:
|
|
|
|
slice[10] += 1;
|
|
|
|
|
|
|
|
// Note that `slice.ptr` does not invoke safety checking, while `&slice[0]`
|
|
|
|
// asserts that the slice has len > 0.
|
2024-06-08 20:39:11 +01:00
|
|
|
|
|
|
|
// Empty slices can be created like this:
|
|
|
|
const empty1 = &[0]u8{};
|
|
|
|
// If the type is known you can use this short hand:
|
|
|
|
const empty2: []u8 = &.{};
|
|
|
|
try expect(empty1.len == 0);
|
|
|
|
try expect(empty2.len == 0);
|
|
|
|
|
|
|
|
// A zero-length initialization can always be used to create an empty slice, even if the slice is mutable.
|
|
|
|
// This is because the pointed-to data is zero bits long, so its immutability is irrelevant.
|
2024-04-25 01:41:47 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
// test_safety=index out of bounds
|