05 · Control de Flujo
Iteración filtrada con for case
for case patrón in valores omite valores que no coinciden y enlaza solo el cuerpo exitoso. Un for común con patrón refutable conserva su panic ante una incompatibilidad. El iterable se evalúa una vez y continue sigue la regla normal del bucle.
En esta página
for case patrón in valores omite valores que no coinciden y enlaza solo el cuerpo exitoso. Un for común con patrón refutable conserva su panic ante una incompatibilidad. El iterable se evalúa una vez y continue sigue la regla normal del bucle.
Ejemplo completo
Iteración filtrada con for case.
for-case.zolo
// 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]))
Reglas y comportamiento
Condiciones y recuperación de errores · Documentación
Desde un checkout del repositorio:
zolo examples/features/for-case.zolo
Consulta también