An optional is just a '?' before the type:
For instance a function which returns an optional pointer to a 'Bla':
fn make_bla() ?*Bla {
// this would either return a valid *Bla, or null
}
A null pointer can't be used accidentally, it must be unwrapped first, and in Zig this is implemented as language syntax, for instance you can unwrap with an if: if (make_bla()) |bla| {
// bla is now the unwrapped valid pointer
} else {
// make_bla() returned null
}
...or with an orelse: const bla = make_bla() orelse { return error.InvalidBla };
...or if you know for sure that bla should be valid, and otherwise want a panic: const bla = make_bla().?;
...error handling with error unions has similar syntax sugar.It's probably not perfect, but I feel that for real-world code, working with optionals and errors in Zig leads to more readable code on average than Rust, while providing the same set of features.