Error handling
cx has no exceptions. Instead, the current idioms for reporting failures are nullable return values and status codes, checked by the caller:
int? parseDigit(char c) {
if c >= '0' && c <= '9' {
return int(c) - int('0');
}
return null;
}
void main() {
if parseDigit('7') {
println("it's a digit");
}
var result = parseDigit('x');
if result == null {
println("not a digit");
}
}See Nullable types for how the compiler checks that nullable values aren't used without a null check.
Result type
When a failure carries information about what went wrong, return a
Result<T, E> holding either the success value
(Ok) or the error (Err):
Result<int, string> parseDigit(char c) {
if c >= '0' && c <= '9' {
return Ok(int(c) - int('0'));
}
return Err("not a digit");
}
void main() {
switch (parseDigit('7')) {
case Ok value:
println(value); // prints 7
case Err error:
println(error);
}
}Use == Ok and == Err to test which case a
result holds. Inside the branch, the variable narrows to the matched
case's payload, so the success value is available directly as
digit.value. The unwrap method returns the
success value, or aborts with the error:
Result<int, string> parseDigit(char c) {
if c >= '0' && c <= '9' {
return Ok(int(c) - int('0'));
}
return Err("not a digit");
}
void main() {
var digit = parseDigit('7');
if digit == Ok {
println(digit.value); // prints 7
}
println(parseDigit('7')!); // prints 7, shorthand for .unwrap()
var notDigit = parseDigit('x');
if notDigit == Err {
println("not a digit");
}
}See Assertions for checking conditions that must hold.