Skip to main content

Control Flow

Oxide provides familiar control flow constructs with some enhancements for safety and expressiveness.

If Expressions

if is an expression that returns a value:

let result = if x > 0 { "positive" } else { "non-positive" }

let message = if score >= 90 {
"Excellent"
} else if score >= 70 {
"Good"
} else {
"Keep practicing"
}

Transpiles to:

let result = if x > 0 { "positive" } else { "non-positive" };

let message = if score >= 90 {
"Excellent"
} else if score >= 70 {
"Good"
} else {
"Keep practicing"
};

If-Let (Optional Binding)

Safely unwrap optionals with if let:

let value: Int? = getValue()

if let val = value {
println!("Got value: $val")
} else {
println!("No value")
}

Transpiles to:

let value: Option<isize> = get_value();

if let Some(val) = value {
println!("Got value: {}", val);
} else {
println!("No value");
}

Guard Statement

Early returns with guard for cleaner code:

fn process(value: Int?) {
guard let v = value else {
println!("No value provided")
return
}
// v is now non-optional and available here
println!("Processing $v")
}

fn validateAge(age: Int): Bool {
guard age >= 0 else { return false }
guard age <= 150 else { return false }
return true
}

Transpiles to:

fn process(value: Option<isize>) {
let v = match value {
Some(v) => v,
None => {
println!("No value provided");
return;
}
};
println!("Processing {}", v);
}

fn validate_age(age: isize) -> bool {
if !(age >= 0) {
return false;
}
if !(age <= 150) {
return false;
}
return true;
}

Match Expression

Pattern matching with match:

match value {
0 -> println!("Zero")
1 -> println!("One")
2..10 -> println!("Small")
else -> println!("Large")
}

// Match as expression
let description = match status {
Status.active -> "Running"
Status.inactive -> "Stopped"
Status.error(msg) -> "Error: $msg"
}

Transpiles to:

match value {
0 => println!("Zero"),
1 => println!("One"),
2..=9 => println!("Small"),
_ => println!("Large"),
}

let description = match status {
Status::active => "Running",
Status::inactive => "Stopped",
Status::error(msg) => format!("Error: {}", msg),
};

Null Pattern

Match null directly for optional types:

fn describe(opt: Int?): String {
match opt {
null -> "No value"
Some(0) -> "Zero"
Some(n) if n > 0 -> "Positive: $n"
Some(n) -> "Negative: $n"
}
}

Transpiles to:

fn describe(opt: Option<isize>) -> String {
match opt {
None => "No value".to_string(),
Some(0) => "Zero".to_string(),
Some(n) if n > 0 => format!("Positive: {}", n),
Some(n) => format!("Negative: {}", n),
}
}

Slice Patterns

Match elements in arrays/slices:

fn describe(arr: &[Int]): String {
match arr {
[] -> "Empty"
[single] -> "One element: $single"
[first, second] -> "Two elements: $first, $second"
[first, .., last] -> "First: $first, Last: $last"
}
}

For Loops

Iterate over collections:

for item in collection {
println!(item)
}

for i in 0..10 {
println!(i) // 0 through 9
}

for i in 0..=10 {
println!(i) // 0 through 10 (inclusive)
}

Transpiles to:

for item in collection {
println!("{}", item);
}

for i in 0..10 {
println!("{}", i);
}

for i in 0..=10 {
println!("{}", i);
}

For-Await (Async Streams)

Iterate over async streams:

for await item in asyncStream {
process(item)
}

Transpiles to:

while let Some(item) = async_stream.next().await {
process(item);
}

While Loops

while condition {
// body
}

// While-let for optionals
while let Some(item) = iterator.next() {
process(item)
}

Loop (Infinite)

loop {
if shouldStop() {
break
}
doWork()
}

// Loop as expression
let result = loop {
let value = compute()
if value > threshold {
break value
}
}

Break and Continue

for i in 0..100 {
if i % 2 == 0 {
continue // Skip even numbers
}
if i > 50 {
break // Stop at 50
}
println!(i)
}

Labeled Loops

'outer: for i in 0..10 {
for j in 0..10 {
if i * j > 25 {
break 'outer // Break outer loop
}
}
}

Ranges

Oxide supports various range syntax:

SyntaxDescriptionRust Equivalent
a..bHalf-open range [a, b)a..b
a..=bClosed range [a, b]a..=b
a..<bHalf-open (alternative)a..b
..bRange to b..b
a..Range from aa..
..Full range..
let first5 = items[0..5]    // Elements 0-4
let last5 = items[-5..] // Last 5 elements
let copy = items[..] // All elements

See Also