ebaklund
ebaklund

Reputation: 271

How to pattern match a String in a struct against a literal

In my code below I find that the code in match_num_works() has a certain elegance. I would like to write a String match with a similar formulation but cannot get it to work. I end up with match_text_works() which is less elegant.

struct FooNum {
    number: i32,
}

// Elegant
fn match_num_works(foo_num: &FooNum) {
    match foo_num {
        &FooNum { number: 1 } => (),
        _ => (),
    }
}

struct FooText {
    text: String,
}

// Clunky
fn match_text_works(foo_text: &FooText) {
    match foo_text {
        &FooText { ref text } => {
            if text == "pattern" {
            } else {
            }
        }
    }
}

// Possible?
fn match_text_fails(foo_text: &FooText) {
    match foo_text {
        &FooText { text: "pattern" } => (),
        _ => (),
    }
}

Upvotes: 1

Views: 243

Answers (2)

Simo Kinnunen
Simo Kinnunen

Reputation: 5947

Note that your desired pattern would actually work with a &str. You can't directly pattern match a String because it's a more complex value that includes an unexposed internal buffer.

struct FooText<'a> {
    text: &'a str,
    _other: u32,
}

fn main() {
    let foo = FooText { text: "foo", _other: 5 };
    match foo {
        FooText { text: "foo", .. } => println!("Match!"),
        _ => println!("No match"),
    }
}

Playground

Upvotes: 0

Simon Whitehead
Simon Whitehead

Reputation: 65079

Its probably not "elegant" or any nicer.. but one option is to move the conditional into the match expression:

match foo_text {
    &FooText { ref text } if text == "pattern" => (),
    _ => ()
}

Working sample: Playpen link.

Upvotes: 5

Related Questions