@@ -771,7 +771,7 @@ and the way in which arrays are expanded is tightly related to
771
771
memory management.
772
772
773
773
774
- ### Selecting elements of the array
774
+ ### Selecting elements of the array {#sec-select-array-elem}
775
775
776
776
One very commom activity is to select specific portions of an array
777
777
you have in your source code.
@@ -917,6 +917,75 @@ try stdout.print("{any}\n", .{c});
917
917
```
918
918
919
919
920
+ ### Runtime versus compile-time known length in slices
921
+
922
+ We are going to talk a lot about the differences between compile-time known
923
+ and runtime known across this book, specially at @sec-compile-time .
924
+ But the basic idea is that a thing is compile-time known, when we know
925
+ everything (the value, the attributes and the characteristics) about this thing at compile-time.
926
+ In contrast, a runtime known thing is when the exact value of a thing is calculated only at runtime.
927
+ Therefore, we don't know the value of this thing at compile-time, only at runtime.
928
+
929
+ We have learned at @sec-select-array-elem that slices are created by using a * range selector* ,
930
+ which represents a range of indexes. When this "range of indexes" (i.e. the start and the end of this range)
931
+ is known at compile-time, the slice object that get's created is actually, under the hood, just
932
+ a single-item pointer to an array.
933
+
934
+ You don't need to precisely understand what that means now. We are going to talk a lot about pointers
935
+ at @sec-pointer . For now, just understand that, when the range of indexes is known at compile-time,
936
+ the slice that get's created is just a pointer to an array, accompanied by a length value that
937
+ tells the size of the slice.
938
+
939
+ If you have a slice object like this, i.e. a slice that has a compile-time known range,
940
+ you can use common pointer operations over this slice object. For example, you can
941
+ dereference the pointer of this slice, by using the ` .* ` method, like you would
942
+ do on a normal pointer object.
943
+
944
+ ``` {zig}
945
+ #| eval: false
946
+ const arr1 = [10]u64 {
947
+ 1, 2, 3, 4, 5,
948
+ 6, 7, 8, 9, 10
949
+ };
950
+ // This slice have a compile-time known range.
951
+ // Because we know both the start and end of the range.
952
+ const slice = arr1[1..4];
953
+ ```
954
+
955
+
956
+ On the other hand, if the range of indexes is not known at compile time, then, the slice object
957
+ that get's created is not a pointer anymore, and, thus, it does not support pointer operations.
958
+ For example, maybe the start index is known at compile time, but the end index is not. In such
959
+ case, the range of the slice becomes runtime known only.
960
+
961
+ In the example below, the ` slice ` object have a runtime known range, because the end index of the range
962
+ is not known at compile time. In other words, the size of the array at ` buffer ` is not known
963
+ at compile time. When we execute this program, the size of the array might be 10, or, it might be 12
964
+ depending on where we execute it. Therefore, we don't know at compile time if
965
+ the slice object have a range of size 10, or, a range of size 12.
966
+
967
+ ``` {zig}
968
+ #| auto_main: false
969
+ #| build_type: "run"
970
+ const std = @import("std");
971
+ const builtin = @import("builtin");
972
+
973
+ pub fn main() !void {
974
+ var gpa = std.heap.GeneralPurposeAllocator(.{}){};
975
+ const allocator = gpa.allocator();
976
+ var n: usize = 0;
977
+ if (builtin.target.os.tag == .windows) {
978
+ n = 10;
979
+ } else {
980
+ n = 12;
981
+ }
982
+ const buffer = try allocator.alloc(u64, n);
983
+ const slice = buffer[0..];
984
+ _ = slice;
985
+ }
986
+ ```
987
+
988
+
920
989
## Blocks and scopes {#sec-blocks}
921
990
922
991
Blocks are created in Zig by a pair of curly braces. A block is just a group of
0 commit comments