Timmmm
Timmmm

Reputation: 96596

Referring to matched value in Rust

Suppose I have this code:

fn non_zero_rand() -> i32 {
    let x = rand();
    match x {
        0 => 1,
        _ => x,
    }
}

Is there a concise way to put the rand() in the match, and then bind it to a value. E.g. something like this:

fn non_zero_rand() -> i32 {
    match let x = rand() {
        0 => 1,
        _ => x,
    }
}

Or maybe:

fn non_zero_rand() -> i32 {
    match rand() {
        0 => 1,
        _x => _x,
    }
}

Upvotes: 17

Views: 6835

Answers (2)

user4815162342
user4815162342

Reputation: 154926

A match arm that consists of just an identifier will match any value, declare a variable named as the identifier, and move the value to the variable. For example:

match rand() {
    0 => 1,
    x => x * 2,
}

A more general way to create a variable and match it is using the @ pattern:

match rand() {
    0 => 1,
    x @ _ => x * 2,
}

In this case it is not necessary, but it can come in useful when dealing with patterens that match many different values, such as range patterns:

match c {
    None => Category::Empty,
    Some(ascii @ 0..=127) => Category::Ascii(ascii),
    Some(latin1 @ 160..=255) => Category::Latin1(latin1),
    _ => Category::Invalid,
}

Playground

Upvotes: 34

belst
belst

Reputation: 2525

You can bind the pattern to a name:

fn non_zero_rand() -> i32 {
    match rand() {
        0 => 1, // 0 is a refutable pattern so it only matches when it fits.
        x => x, // the pattern is x here,
                // which is non refutable, so it matches on everything
                // which wasn't matched already before
    }
}

Upvotes: 3

Related Questions