Slices

test.zig

  1. constassert=@import("std").debug.assert;
  2. test "basic slices"{
  3. var array =[_]i32{1,2,3,4};
  4. // A slice is a pointer and a length. The difference between an array and
  5. // a slice is that the array's length is part of the type and known at
  6. // compile-time, whereas the slice's length is known at runtime.
  7. // Both can be accessed with the `len` field.
  8. var known_at_runtime_zero: usize =0;
  9. const slice = array[known_at_runtime_zero..array.len];
  10. assert(&slice[0]==&array[0]);
  11. assert(slice.len == array.len);
  12. // Using the address-of operator on a slice gives a pointer to a single
  13. // item, while using the `ptr` field gives an unknown length pointer.
  14. assert(@TypeOf(slice.ptr)==[*]i32);
  15. assert(@TypeOf(&slice[0])==*i32);
  16. assert(@ptrToInt(slice.ptr)==@ptrToInt(&slice[0]));
  17. // Slices have array bounds checking. If you try to access something out
  18. // of bounds, you'll get a safety check failure:
  19. slice[10]+=1;
  20. // Note that `slice.ptr` does not invoke safety checking, while `&slice[0]`
  21. // asserts that the slice has len >= 1.
  22. }
  1. $ zig test test.zig
  2. 1/1 test "basic slices"...index out of bounds
  3. /deps/zig/docgen_tmp/test.zig:22:10:0x204cc6in test "basic slices"(test)
  4. slice[10]+=1;
  5. ^
  6. /deps/zig/lib/std/special/test_runner.zig:47:28:0x22bc1ein std.special.main (test)
  7. }else test_fn.func();
  8. ^
  9. /deps/zig/lib/std/start.zig:253:37:0x20574din std.start.posixCallMainAndExit (test)
  10. const result = root.main()catch|err|{
  11. ^
  12. /deps/zig/lib/std/start.zig:123:5:0x20548fin std.start._start (test)
  13. @call(.{.modifier =.never_inline }, posixCallMainAndExit,.{});
  14. ^
  15. Tests failed.Use the following command to reproduce the failure:
  16. /deps/zig/docgen_tmp/test

This is one reason we prefer slices to pointers.

slices.zig

  1. const std =@import("std");
  2. constassert= std.debug.assert;
  3. const mem = std.mem;
  4. const fmt = std.fmt;
  5. test "using slices for strings"{
  6. // Zig has no concept of strings. String literals are const pointers to
  7. // arrays of u8, and by convention parameters that are "strings" are
  8. // expected to be UTF-8 encoded slices of u8.
  9. // Here we coerce [5]u8 to []const u8
  10. const hello:[]const u8 ="hello";
  11. const world:[]const u8 ="世界";
  12. var all_together:[100]u8 =undefined;
  13. // You can use slice syntax on an array to convert an array into a slice.
  14. const all_together_slice = all_together[0..];
  15. // String concatenation example.
  16. const hello_world =try fmt.bufPrint(all_together_slice,"{} {}",.{ hello, world });
  17. // Generally, you can use UTF-8 and not worry about whether something is a
  18. // string. If you don't need to deal with individual characters, no need
  19. // to decode.
  20. assert(mem.eql(u8, hello_world,"hello 世界"));
  21. }
  22. test "slice pointer"{
  23. var array:[10]u8 =undefined;
  24. const ptr =&array;
  25. // You can use slicing syntax to convert a pointer into a slice:
  26. const slice = ptr[0..5];
  27. slice[2]=3;
  28. assert(slice[2]==3);
  29. // The slice is mutable because we sliced a mutable pointer.
  30. // Furthermore, it is actually a pointer to an array, since the start
  31. // and end indexes were both comptime-known.
  32. assert(@TypeOf(slice)==*[5]u8);
  33. // You can also slice a slice:
  34. const slice2 = slice[2..3];
  35. assert(slice2.len ==1);
  36. assert(slice2[0]==3);
  37. }
  1. $ zig test slices.zig
  2. 1/2 test "using slices for strings"...OK
  3. 2/2 test "slice pointer"...OK
  4. All2 tests passed.

See also:

Sentinel-Terminated Slices

The syntax [:x]T is a slice which has a runtime known length and also guarantees a sentinel value at the element indexed by the length. The type does not guarantee that there are no sentinel elements before that. Sentinel-terminated slices allow element access to the len index.

null_terminated_slice.zig

  1. const std =@import("std");
  2. constassert= std.debug.assert;
  3. test "null terminated slice"{
  4. const slice:[:0]const u8 ="hello";
  5. assert(slice.len ==5);
  6. assert(slice[5]==0);
  7. }
  1. $ zig test null_terminated_slice.zig
  2. 1/1 test "null terminated slice"...OK
  3. All1 tests passed.

See also: