Skip to content

05 · Control Flow

Filtering iteration with for case

for case pattern in values skips values that do not match, binding only the successful body. A plain refutable for loop retains its mismatch panic. The iterable is evaluated once and continue targets the filtering loop normally.

On this page

for case pattern in values skips values that do not match, binding only the successful body. A plain refutable for loop retains its mismatch panic. The iterable is evaluated once and continue targets the filtering loop normally.

Complete example

Filtering iteration with for case.

for-case.zolo
Playground
// Filtering loops evaluate their input once and skip non-matching elements.

var acquisitions = 0
fn results() -> [Result<int, str>] {
    acquisitions += 1;
    [.Ok(1), .Err("skip"), .Ok(2), .Ok(3)]
}
var total = 0
var events = ""
let __zolo_for_case_0 = 100
for case .Ok(value) in results() {
    assert(__zolo_for_case_0 == 100)
    defer { events += "{value}" }
    if value == 2 { continue }
    total += value
}
print(total) // expect: 4

print(acquisitions) // expect: 1

print(events) // expect: 123


let candidates: [Result<int,str>] = [.Ok(1), .Err("skip"), .Ok(2)]
var labels = 0
:outer for round in 0..3 {
    for case .Ok(value) in candidates {
        labels += 1
        if round == 0 && value == 1 { continue :outer }
        if round == 1 && value == 2 { break :outer }
    }
}
print(labels) // expect: 3


var hits = 0
for case 1 | 3 in [1, 2, 3] { hits += 1 }
print(hits) // expect: 2


let optional: [int?] = [1, nil, 3]
var wildcards = 0
var nils = 0
for case _ in optional { wildcards += 1 }
for case nil in optional { nils += 1 }
print(wildcards) // expect: 3

print(nils) // expect: 1


let options: [Option<int>] = [.Some(8), .None]
for case whole @ .Some(value) in options {
    let original: Option<int> = whole
    print(value) // expect: 8

    print(original.unwrap()) // expect: 8

}

// A matching body's linear resources still follow their own using scope.

@linear struct Resource { id: int }
impl core::cleanup::Cleanup for Resource {
    fn close(self) { print("close"); print(self.id) }
}
let resources: [Result<int,str>] = [.Ok(4), .Err("skip"), .Ok(5)]
for case .Ok(value) in resources {
    using resource = Resource { id: value } {
        if value == 4 { continue }
        break
    }
}
// expect: close

// expect: 4

// expect: close

// expect: 5


// Numeric range bounds are frozen before the body and end without overflow.

let maximum = 9223372036854775807
let minimum = -maximum - 1
let start = 0
var starts = 0
for case value in start..({ start = 3; 4 }) { starts += 1 }
print(starts) // expect: 4

let end = 4
var ends = 0
for case value in 0..end { end = 0; ends += 1 }
print(ends) // expect: 4

var singleton = 0
for case value in maximum..=maximum { singleton += 1; continue }
print(singleton) // expect: 1

var empty = 0
for case value in minimum..minimum { empty += 1 }
print(empty) // expect: 0

var opened = 0
for case value in maximum.. { assert(value == maximum); opened += 1; break }
print(opened) // expect: 1


// Iterator return stays in the caller and closes its enclosing resource.

fn header_return() -> int {
    let values: [Result<int, str>] = [.Ok(1)]
    using resource = Resource { id: 9 } {
        for case .Ok(item) in ({ return 7; values }) {}
    }
    99
}
print(header_return())
// expect: close

// expect: 9

// expect: 7


// Filtering strings uses Unicode scalar elements rather than UTF-8 bytes.

var unicode_hits = 0
var unicode_count = 0
var unicode_text = ""
for case "é" in "é🙂" { unicode_hits += 1 }
for case character in "é🙂" { unicode_count += 1; unicode_text += character }
print(unicode_hits)
print(unicode_count)
print(unicode_text)
macro count_elements(values) { var count = 0; for case _ in $values { count += 1 }; count }
print(count_elements!("é🙂"))
print(count_elements!([1, 2, 3]))

Rules and behavior

Conditions and error recovery · Documentation

From a checkout of the repository:

zolo examples/features/for-case.zolo

Global index

Find your way through Zolo

Try an idea

Start here

9 results

9 results

enespt-br