Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Referring to matched value in Rust

Tags:

match

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,
    }
}
like image 725
Timmmm Avatar asked Dec 04 '16 18:12

Timmmm


People also ask

How do I use a match statement in Rust?

Match Statement in Rust We will start with the keyword match, and then compare the variable to use the match construct. We then open the match body, which takes the case as a “matched” value against the specified variable's value. In the previous example, we start by initializing the variable age.

What does REF mean in Rust?

Keyword refBind by reference during pattern matching. ref annotates pattern bindings to make them borrow rather than move. It is not a part of the pattern as far as matching is concerned: it does not affect whether a value is matched, only how it is matched.

Does Rust have pattern matching?

Patterns are a special syntax in Rust for matching against the structure of types, both complex and simple. Using patterns in conjunction with match expressions and other constructs gives you more control over a program's control flow.

What are match expressions?

A match expression branches on a pattern. The exact form of matching that occurs depends on the pattern. A match expression has a scrutinee expression, which is the value to compare to the patterns.


2 Answers

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 useful when dealing with conditional matches such as ranges:

match code {
    None => Empty,
    Some(ascii @ 0..=127) => Ascii(ascii as u8),
    Some(latin1 @ 160..=255) => Latin1(latin1 as u8),
    _ => Invalid
}
like image 70
user4815162342 Avatar answered Sep 29 '22 11:09

user4815162342


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
    }
}
like image 20
belst Avatar answered Sep 29 '22 11:09

belst