Brian Oh
Brian Oh

Reputation: 10780

What happens in Rust using "match" if nothing matches?

I'm learning Rust and it looks very interesting. I'm not yet very familiar with "match", but it looks to be fairly integral. I was using the following code (below) to convert String to i64 which included the commented-out line "None" in place of the next line "_". I wondered what happened in the event of a non-match without underscore or whether "None" may be a catch-all. The calling-code requires a positive i64, so negative results in an invalid input (in this case). I'm not sure if it's possible to indicate an error in a return using this example other than perhaps using a struct.

  1. Without underscore as a match item, will "None" catch all, and can it be used instead of underscore?

  2. Is it possible to return an error in a function like this without using a struct as the return value?

  3. In general, is it possible for a non-match using "match" and if so, what happens?

  4. In the example below, is there any difference between using underscore and using "None"?

Example code :

fn fParseI64(sVal: &str) -> i64 {
    match from_str::<i64>(sVal) {
        Some(iVal) => iVal,
//        None => -1
     _ => -1    
    }
}

Upvotes: 7

Views: 9376

Answers (1)

Dogbert
Dogbert

Reputation: 222388

  1. Without underscore as a match item, will "None" catch all, and can it be used instead of underscore?

In this case, yes. There are only 2 cases for Option<T>: Some<T> or None. You are already matching the Some case for all values, None is the only case that's left, so None will behave exactly the same as _.

 2. Is it possible to return an error in a function like this without using a struct as the return value?

I'd suggest you read this detailed guide to understand all the possible ways to handle errors - http://static.rust-lang.org/doc/master/tutorial-conditions.html

Using Options and Results will require you to return a struct.

 3. In general, is it possible for a non-match using "match" and if so, what happens?

Rust won't compile a match if it can't guarantee that all the possible cases are handled. You'll need to have a _ clause if you are not matching all possibilities.

 4. In the example below, is there any difference between using underscore and using "None"?

No. See Answer #1.

Here are 3 of the many ways you can write your function:

// Returns -1 on wrong input.
fn alt_1(s: &str) -> i64 {
  match from_str::<i64>(s) {
    Some(i) => if i >= 0 {
      i
    } else {
      -1
    },
    None => -1
  }
}

// Returns None on invalid input.
fn alt_2(s: &str) -> Option<i64> {
  match from_str::<i64>(s) {
    Some(i) => if i >= 0 {
      Some(i)
    } else {
      None
    },
    None => None
  }
}

// Returns a nice message describing the problem with the input, if any.
fn alt_3(s: &str) -> Result<i64, ~str> {
  match from_str::<i64>(s) {
    Some(i) => if i >= 0 {
      Ok(i)
    } else {
      Err(~"It's less than 0!")
    },
    None => Err(~"It's not even a valid integer!")
  }
}

fn main() {
  println!("{:?}", alt_1("123"));
  println!("{:?}", alt_1("-123"));
  println!("{:?}", alt_1("abc"));

  println!("{:?}", alt_2("123"));
  println!("{:?}", alt_2("-123"));
  println!("{:?}", alt_2("abc"));

  println!("{:?}", alt_3("123"));
  println!("{:?}", alt_3("-123"));
  println!("{:?}", alt_3("abc"));
}

Output:

123i64
-1i64
-1i64
Some(123i64)
None
None
Ok(123i64)
Err(~"It's less than 0!")
Err(~"It's not even a valid integer!")

Upvotes: 10

Related Questions