@@ -97,7 +97,7 @@ if (x > 10) {
97
97
98
98
99
99
100
- ### Swith statements {#sec-switch}
100
+ ### Switch statements {#sec-switch}
101
101
102
102
Switch statements are also available in Zig.
103
103
A switch statement in Zig have a similar syntax to a switch statement in Rust.
@@ -1043,11 +1043,8 @@ is commonly used on switch statements in Zig.
1043
1043
## Modules
1044
1044
1045
1045
We already talked about what modules are, and also, how to import other modules into
1046
- you current module through * import statements* , so that you can use functionality from these other modules in
1047
- your current module.
1048
- But in this section, I just want to make it clear that modules are actually structs in Zig.
1049
-
1050
- In other words, every Zig module (i.e. a ` .zig ` file) that you write in your project
1046
+ you current module through * import statements* .
1047
+ Every Zig module (i.e. a ` .zig ` file) that you write in your project
1051
1048
is internally stored as a struct object.
1052
1049
Take the line exposed below as an example. In this line we are importing the
1053
1050
Zig Standard Library into our current module.
@@ -1089,3 +1086,89 @@ const pool = ThreadPool.init(
1089
1086
.{ .max_threads = num_threads }
1090
1087
);
1091
1088
```
1089
+
1090
+
1091
+
1092
+ ## Type casting {#sec-type-cast}
1093
+
1094
+ In this section, I want to discuss type casting (or, type conversion) with you.
1095
+ We use type casting when we have an object of type "x", and we want to convert
1096
+ it into an object of type "y", i.e. we want to change the data type of the object.
1097
+
1098
+ Most languages have a formal way to perform type casting. In Rust for example, we normally
1099
+ use the keyword ` as ` , and in C, we normally use the type casting syntax, e.g. ` (int) x ` .
1100
+ In Zig, we use the ` @as() ` built-in function to cast an object of type "x", into
1101
+ an object of type "y".
1102
+
1103
+ This ` @as() ` function is the preferred way to perform type conversion (or type casting)
1104
+ in Zig. Because it is explicit, and, it also performs the casting only if it
1105
+ is unambiguous and safe. To use this function, you just provide the target data type
1106
+ in the first argument, and, the object that you want cast at the second argument.
1107
+
1108
+ ``` {zig}
1109
+ #| auto_main: false
1110
+ #| build_type: "test"
1111
+ const std = @import("std");
1112
+ const expect = std.testing.expect;
1113
+ test {
1114
+ const x: usize = 500;
1115
+ const y = @as(u32, x);
1116
+ try expect(@TypeOf(y) == u32);
1117
+ }
1118
+ ```
1119
+
1120
+ This is the general way to perform type casting in Zig. But remember, ` @as() ` works only when casting
1121
+ is unambiguous and safe, and there are situations where these assumptions do not hold. For example,
1122
+ when casting an integer value into a float value, or vice-versa, it is not clear to the compiler
1123
+ how to perform this conversion safely.
1124
+
1125
+ Therefore, we need to use specialized "casting functions" in such situations.
1126
+ For example, if you want to cast an integer value into a float value, then, you
1127
+ should use the ` @floatFromInt() ` function. In the inverse scenario, you should use
1128
+ the ` @intFromFloat() ` function.
1129
+
1130
+ In these functions, you just provide the object that you want to
1131
+ cast as input. Then, the target data type of the "type casting operation" is determined by
1132
+ the type annotation of the object where you are saving the results.
1133
+ In the example below, we are casting the object ` x ` into a value of type ` f32 ` ,
1134
+ because the object ` y ` , which is where we are saving the results, is annotated
1135
+ as an object of type ` f32 ` .
1136
+
1137
+ ``` {zig}
1138
+ #| auto_main: false
1139
+ #| build_type: "test"
1140
+ const std = @import("std");
1141
+ const expect = std.testing.expect;
1142
+ test {
1143
+ const x: usize = 565;
1144
+ const y: f32 = @floatFromInt(x);
1145
+ try expect(@TypeOf(y) == f32);
1146
+ }
1147
+ ```
1148
+
1149
+ Another built-in function that is very useful when performing type casting operations is ` @ptrCast() ` .
1150
+ In essence, we use the ` @as() ` built-in function when we want to explicit convert (or cast) a Zig value/object
1151
+ from a type "x" to a type "y", etc. However, pointers (we are going to discuss pointers
1152
+ in more depth at @sec-pointer ) are a special type of object in Zig,
1153
+ i.e. they are treated differently from "normal objects".
1154
+
1155
+ Everytime a pointer is involved in some "type casting operation" in Zig, the ` @ptrCast() ` function is used.
1156
+ This function works similarly to ` @floatFromInt() ` .
1157
+ You just provide the pointer object that you want to cast as input to this function, and the
1158
+ target data type is, once again, determined by the type annotation of the object where the results are being
1159
+ stored.
1160
+
1161
+ ``` {zig}
1162
+ #| auto_main: false
1163
+ #| build_type: "test"
1164
+ const std = @import("std");
1165
+ const expect = std.testing.expect;
1166
+ test {
1167
+ const bytes align(@alignOf(u32)) = [_]u8{
1168
+ 0x12, 0x12, 0x12, 0x12
1169
+ };
1170
+ const u32_ptr: *const u32 = @ptrCast(&bytes);
1171
+ try expect(@TypeOf(u32_ptr) == *const u32);
1172
+ }
1173
+ ```
1174
+
0 commit comments