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); }