Can guards be used in switch and while, not just if?
← Control Flow · Ref: Q975
Yes. The same 'v <- expression' guard works in if, switch, while and try: it means 'declare v, check if SET, only proceed if SET'. One difference to know: in a loop the guard is evaluated ONCE, on entry (if it is unset the body is skipped); only the 'with' condition is re-tested on every iteration.
IN IF:
if name <- findUser(id) stdout.println(name)
IN SWITCH:
switch kind <- database.kindOf(id) with kind case == "USER" processUser(kind) default processOther(kind)
IN WHILE (the guard runs once; 'with' is the per-iteration test):
while conn <- openConnection() with counter < maxIters process(conn) counter: counter + 1
IN TRY:
try connection <- openDatabase() query(connection) catch -> ex as Exception logError(ex)
The guard syntax is the same everywhere - one syntax to learn. This eliminates 90-95% of null pointer exceptions across ALL control flow.
See Q971 for if guard details. See Q75 for switch guard details.
Example
defines module qa.controlflow.guardcontexts defines function <?- Returns a set or unset value based on input. -?> fetchValue() as pure -> key as String <- rtn as String: String() if key? rtn: "Value for " + key defines program GuardContextsDemo() stdout <- Stdout() // Guard in IF if greeting <- fetchValue("hello") stdout.println(`IF guard: ${greeting}`) // Guard in IF with else if missing <- fetchValue(String()) stdout.println(missing) else stdout.println("IF guard: skipped because unset") // Guard in SWITCH switch found <- fetchValue("test") with found case == "Value for test" stdout.println(`SWITCH guard: exact match`) default stdout.println(`SWITCH guard: ${found}`)
Common mistakes
E01073 — 'null' does not exist in EK9; check a value with the '?' isSet operator, not '!= null'. See ek9 -h E01073 for details.
Incorrect:
if key != null
Correct:
if key?
Other ways to ask this
- Where can I use the <- guard pattern in EK9?
- Does the declaration guard work in switch statements?
- Show me guards in while loops in EK9
- Is the if v <- expr guard universal across EK9 control flow?
- Can I use guards in switch statements and while loops, not just if?
- Show me guards in a switch statement in EK9
- How do guards work in while loops in EK9?
- Do EK9 guards work in all control flow constructs?
Coming from another language?
Go: if err := f(); err != nil — only works in if. Rust: if let — only works in if/while. Swift: if let — only in if. EK9: the same guard syntax works in if, switch, while, and try (in a loop the guard is evaluated once, 'with' is re-tested).
Keywords: universal, try, try guard, while, switch guard, guard, switch, while guard, control flow