# switch

> Branch on a value against constant case labels. Only the matched section runs (no fall-through); a default section handles the rest. break exits the switch; continue continues the enclosing loop.

<!-- id: function-switch · area: function · stability: stable · html: https://osysharp.com/reference/function/switch/ -->

## Summary        {#summary}
`switch (scrutinee) { … }` branches on a value against constant `case` labels, running the first matching
section (or `default` if none match). Only the matched section runs — there is **no implicit
fall-through** — so a trailing `break` is idiomatic but optional. `break` exits the switch; `continue`
inside a switch continues the **enclosing loop**.

## Signature      {#signature}
```osy syntax
switch (<scrutinee>) {
  case <const>:
  case <const>:      // stacked labels share a body
    <statements>
    break;           // optional — sections never fall through
  default:
    <statements>
}
```

## Description    {#description}
- **Case labels are compile-time constants** — literals, enum members, or `const`s — comparable to the
  scrutinee's type (`int`, `string`, `enum`, `bool`). A non-constant or type-incompatible label is a
  compile error.
- **Stacked labels** (`case 1: case 2:`) share one body.
- **`default`** runs when no case matches; at most one is allowed, and it may appear anywhere.
- **No fall-through**: only the matched section runs, then the switch exits. A trailing `break` is
  accepted (and idiomatic) but not required — unlike C#, Osy# sections never fall through, so a missing
  break is not an error.
- **`break`** exits the switch (it is a break boundary, not a loop). **`continue`** inside a switch that
  sits in a loop continues that **loop** (it passes through the switch) — exactly C#.
- A function whose value is produced entirely by a switch needs an exhaustive switch (a `default` where
  every section returns) to satisfy definite-return.
- Durable: a suspend inside a case body survives serialize/restore.

## Examples       {#examples}
```osy title="switch" test app=switch-examples
string Grade(int score) {
  switch (score) {
    case 5: case 4: return "pass";     // stacked labels
    case 3: return "marginal";
    default: return "fail";
  }
}

int Code(string s) {
  switch (s) {                          // switch on a string
    case "red": return 1;
    case "green": return 2;
    default: return 0;
  }
}

// break exits the SWITCH, not the loop; continue continues the LOOP.
int Scan(int[] xs) {
  int total = 0;
  for (int i = 0; i < xs.Length; i++) {
    switch (xs[i]) {
      case 0: continue;                 // skip zeros — continues the for loop
      default: break;                   // exits the switch, falls to the += below
    }
    total = total + xs[i];
  }
  return total;
}
```

## See also       {#see-also}
- [if / else](https://osysharp.com/reference/function/if/) — the two-way / chained conditional
- [break / continue](https://osysharp.com/reference/function/break-continue/) — how break and continue behave in loops vs switch
- [for](https://osysharp.com/reference/function/for-loop/) — the loop `continue` targets when inside a switch
