? Fallback Unwrap
The source form is:
result_expr ? fallback_expr
For Result<T>, ? yields the success value when the receiver succeeds
and the explicit fallback when the receiver is an error.
| Input | Output |
|---|---|
Result(_, V, false) ? F |
V |
Result(_, _, true) ? F |
F |
Example
func:maybe_number = int32(bool:ok) {
if (ok) {
pass 42i32;
};
fail 7i32;
};
func:main = int32() {
int32:a = maybe_number(true) ? 0i32; // 42
int32:b = maybe_number(false) ? 0i32; // 0
exit a - b;
};
Not propagation
? is not Rust-style propagation. It does not automatically return from
the current function on error. The fallback is mandatory and local.
int32:x = might_fail() ? 10i32; // local fallback
If the fallback should depend on the error code, use contextual catch:
int32:x = might_fail() catch (err) { err + 10i32 };
Type checking
The fallback expression must match the unwrapped value type T, or be
coercible under the ordinary literal/assignment rules.
int32:x = maybe_number(false) ? 0i32; // OK
// int32:y = maybe_number(false) ? "no"; // type error
Nested fallback is explicit
Nested Results keep their own state until you handle them:
func:inner = int32() { fail 4i32; };
func:outer = int32() {
int32:x = inner() ? 14i32;
pass x;
};
The inner() failure does not silently become an outer() failure.
await shape
v0.33.1 locked this parser shape:
await work() ? fallback == (await work()) ? fallback
The await operand consumes call/member/index postfixes, but leaves Result fallback operators for the outer expression.