rhai/doc/src/language/switch.md
2020-11-14 09:38:16 +08:00

3.1 KiB

switch Expression

{{#include ../links.md}}

The switch expression allows matching on literal values, and it mostly follows Rust's match syntax:

switch calc_secret_value(x) {
    1 => print("It's one!"),
    2 => {
        print("It's two!");
        print("Again!");
    }
    3 => print("Go!"),
    // _ is the default when no cases match
    _ => print("Oops! Something's wrong: " + x)
}

Expression, Not Statement

switch is not a statement, but an expression. This means that a switch expression can appear anywhere a regular expression can, e.g. as function call arguments.

let x = switch foo { 1 => true, _ => false };

func(switch foo {
    "hello" => 42,
    "world" => 123,
    _ => 0
});

// The above is somewhat equivalent to:

let x = if foo == 1 { true } else { false };

if foo == "hello" {
    func(42);
} else if foo == "world" {
    func(123);
} else {
    func(0);
}

Array and Object Map Literals Also Work

The switch expression can match against any literal, including [array] and [object map] literals.

// Match on arrays
switch [foo, bar, baz] {
    ["hello", 42, true] => { ... }
    ["hello", 123, false] => { ... }
    ["world", 1, true] => { ... }
    _ => { ... }
}

// Match on object maps
switch map {
    #{ a: 1, b: 2, c: true } => { ... }
    #{ a: 42, d: "hello" } => { ... }
    _ => { ... }
}

Switching on [arrays] is very useful when working with Rust enums (see this chapter for more details).

Difference From if - else if Chain

Although a switch expression looks almost the same as an if-else if chain, there are subtle differences between the two.

Look-up Table vs x == y

A switch expression matches through hashing via a look-up table. Therefore, matching is very fast. Walking down an if-else if chain is much slower.

On the other hand, operators can be [overloaded][operator overloading] in Rhai, meaning that it is possible to override the == operator for integers such that x == y returns a different result from the built-in default.

switch expressions do not use the == operator for comparison; instead, they hash the data values and jump directly to the correct statements via a pre-compiled look-up table. This makes matching extremely efficient, but it also means that [overloading][operator overloading] the == operator will have no effect.

Therefore, in environments where it is desirable to [overload][operator overloading] the == operator - though it is difficult to think of valid scenarios where you'd want 1 == 1 to return something other than true - avoid using the switch expression.

Efficiency

Because the switch expression works through a look-up table, it is very efficient even for large number of cases; in fact, switching is an O(1) operation regardless of the size of the data and number of cases to match.

A long if-else if chain becomes increasingly slower with each additional case because essentially an O(n) linear scan is performed.