mirror of
https://github.com/odin-lang/Odin.git
synced 2026-06-08 19:44:20 +00:00
Add or_return_operator to examples/demo
This commit is contained in:
@@ -1998,9 +1998,9 @@ relative_data_types :: proc() {
|
||||
fmt.println(rel_slice[1]);
|
||||
}
|
||||
|
||||
or_else_procedure :: proc() {
|
||||
or_else_operator :: proc() {
|
||||
fmt.println("\n#'or_else'");
|
||||
// IMPORTANT NOTE: 'or_else' is experimental features and subject to change/removal
|
||||
// IMPORTANT NOTE: 'or_else' is an experimental feature and subject to change/removal
|
||||
{
|
||||
m: map[string]int;
|
||||
i: int;
|
||||
@@ -2029,6 +2029,102 @@ or_else_procedure :: proc() {
|
||||
}
|
||||
}
|
||||
|
||||
or_return_operator :: proc() {
|
||||
fmt.println("\n#'or_return'");
|
||||
// IMPORTANT NOTE: 'or_return' is an experimental feature and subject to change/removal
|
||||
//
|
||||
// The concept of 'or_return' will work by popping off the end value in a multiple
|
||||
// valued expression and checking whether it was not 'nil' or 'false', and if so,
|
||||
// set the end return value to value if possible. If the procedure only has one
|
||||
// return value, it will do a simple return. If the procedure had multiple return
|
||||
// values, 'or_return' will require that all parameters be named so that the end
|
||||
// value could be assigned to by name and then an empty return could be called.
|
||||
|
||||
Error :: enum {
|
||||
None,
|
||||
Something_Bad,
|
||||
Something_Worse,
|
||||
The_Worst,
|
||||
Your_Mum,
|
||||
};
|
||||
|
||||
caller_1 :: proc() -> Error {
|
||||
return .None;
|
||||
}
|
||||
|
||||
caller_2 :: proc() -> (int, Error) {
|
||||
return 123, .None;
|
||||
}
|
||||
|
||||
foo_1 :: proc() -> Error {
|
||||
// This can be a common idiom in many code bases
|
||||
n0, err := caller_2();
|
||||
if err != nil {
|
||||
return err;
|
||||
}
|
||||
|
||||
// The above idiom can be transformed into the follow
|
||||
n1 := caller_2() or_return;
|
||||
|
||||
|
||||
// And if the expression has no other, it can be used like this
|
||||
caller_1() or_return;
|
||||
// which is functionally equivalen to
|
||||
if err1 := caller_1(); err1 != nil {
|
||||
return err1;
|
||||
}
|
||||
|
||||
_, _ = n0, n1;
|
||||
return .None;
|
||||
}
|
||||
foo_2 :: proc() -> (n: int, err: Error) {
|
||||
// It is more common that your procedure turns multiple values
|
||||
// If 'or_return' is used within a procedure multiple parameters (2+),
|
||||
// then all the parameters must be named so that the remaining parameters
|
||||
// so that a bare 'return' statement can be used
|
||||
|
||||
// This can be a common idiom in many code bases
|
||||
x: int;
|
||||
x, err = caller_2();
|
||||
if err != nil {
|
||||
return;
|
||||
}
|
||||
|
||||
// The above idiom can be transformed
|
||||
y := caller_2() or_return;
|
||||
|
||||
// And if the expression has no other, it can be used like this
|
||||
caller_1() or_return;
|
||||
|
||||
// which is functionally equivalen to
|
||||
if err1 := caller_1(); err1 != nil {
|
||||
err = err1;
|
||||
return;
|
||||
}
|
||||
|
||||
// If a the other values need to be set depending on what the end value is,
|
||||
// the 'defer if' is can be used
|
||||
defer if err != nil {
|
||||
n = -1;
|
||||
}
|
||||
|
||||
// If a non-bare return is required, then a normal if is a lot clearer
|
||||
// and gets around the short circuiting
|
||||
if z, zerr := caller_2(); zerr != nil {
|
||||
n = -z;
|
||||
err = zerr;
|
||||
return;
|
||||
}
|
||||
|
||||
n = 123;
|
||||
return;
|
||||
}
|
||||
|
||||
foo_1();
|
||||
foo_2();
|
||||
}
|
||||
|
||||
|
||||
main :: proc() {
|
||||
when true {
|
||||
the_basics();
|
||||
@@ -2061,7 +2157,7 @@ main :: proc() {
|
||||
union_maybe();
|
||||
explicit_context_definition();
|
||||
relative_data_types();
|
||||
or_else_procedure();
|
||||
or_else_operator();
|
||||
or_return_operator();
|
||||
}
|
||||
}
|
||||
//
|
||||
Reference in New Issue
Block a user