Optionals
?T makes nullability explicit. Plain *T is never null.
var maybe: ?i32 = null;
maybe = 42;
// 1. orelse: provide a default
const a = maybe orelse 0;
// 2. .? : unwrap or panic (asserts non-null)
const b = maybe.?;
// 3. if capture
if (maybe) |value| {
std.debug.print("{d}\n", .{value});
}
// 4. Pointer capture to modify in place
if (maybe) |*value| value.* += 1;
// 5. orelse with control flow
const c = maybe orelse return; // or: orelse break, orelse continue, orelse unreachable
_ = .{ a, b, c };
// Optional pointers have the same size as normal pointers (null = address 0)
var node: ?*Node = null;
while (node) |n| : (node = n.next) {
std.debug.print("{d}\n", .{n.value});
}
fn find(items: []const i32, target: i32) ?usize {
for (items, 0..) |item, i| if (item == target) return i;
return null;
}