From ee9b8fc921f48dc893808e1c9dbfbef321aa362c Mon Sep 17 00:00:00 2001 From: Nguyễn Gia Phong Date: Sun, 28 Feb 2021 17:18:03 +0700 Subject: [lang/zig] Learn some Zig --- lang/zig/slices.zig | 77 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 77 insertions(+) create mode 100644 lang/zig/slices.zig (limited to 'lang/zig/slices.zig') diff --git a/lang/zig/slices.zig b/lang/zig/slices.zig new file mode 100644 index 0000000..8356c26 --- /dev/null +++ b/lang/zig/slices.zig @@ -0,0 +1,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); +} -- cgit 1.4.1