1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
|
const bufPrint = std.fmt.bufPrint;
const eql = std.mem.eql;
const expect = std.testing.expect;
const std = @import("std");
test "basic slices" {
var array = [_]i32{ 1, 2, 3, 4 };
// A slice is a pointer and a length. The difference between an array and
// a slice is that the array's length is part of the type and known at
// compile-time, whereas the slice's length is known at runtime.
// Both can be accessed with the `len` field.
var known_at_runtime_zero: usize = 0;
const slice = array[known_at_runtime_zero..array.len];
expect(&slice[0] == &array[0]);
expect(slice.len == array.len);
// Using the address-of operator on a slice gives a pointer to a single
// item, while using the `ptr` field gives an unknown length pointer.
expect(@TypeOf(slice.ptr) == [*]i32);
expect(@TypeOf(&slice[0]) == *i32);
expect(@ptrToInt(slice.ptr) == @ptrToInt(&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 >= 1.
}
test "using slices for strings" {
// Zig has no concept of strings. String literals are const pointers to
// arrays of u8, and by convention parameters that are "strings" are
// expected to be UTF-8 encoded slices of u8.
// Here we coerce [5]u8 to []const u8
const hello: []const u8 = "hello";
const world: []const u8 = "世界";
var all_together: [100]u8 = undefined;
// String concatenation example.
const hello_world = try bufPrint(
all_together[0..], "{} {}", .{ hello, world });
// Generally, you can use UTF-8 and not worry about whether something is a
// string. If you don't need to deal with individual characters, no need
// to decode.
expect(eql(u8, hello_world, "hello 世界"));
}
test "slice pointer" {
var array: [10]u8 = undefined;
const ptr = &array;
// You can use slicing syntax to convert a pointer into a slice:
const slice = ptr[0..5];
slice[2] = 3;
expect(slice[2] == 3);
// The slice is mutable because we sliced a mutable pointer.
// Furthermore, it is actually a pointer to an array, since the start
// and end indexes were both comptime-known.
expect(@TypeOf(slice) == *[5]u8);
// You can also slice a slice:
const slice2 = slice[2..3];
expect(slice2.len == 1);
expect(slice2[0] == 3);
}
test "null terminated slice" {
const string = "hello";
const slice: [:0]const u8 = string;
expect(@TypeOf(string) == *const [5:0]u8);
expect(@TypeOf(slice) == [:0]const u8);
expect(slice.len == 5);
expect(slice[5] == 0);
}
|