Insert Title

Okt 19, 2017

Rust: if let .... not

Introduction

Rust's error handling can be very exhaustive, both in terms of safety and verbosity. Consider the following example:

match get() {
    Some(value) => {
        println!("Do something with value: {}", value);
    },
    None => {}
}

If you have a lot of statements like this, your code can get very verbose, which is why this has been addressed by the if let syntax:

if let Some(value) = get() {
    println!("Do something with value: {}", value);
} else { /* error handling here */ }

Now this is much shorter, but what if you have multiple chained operations? Of course you can use and_then, but this will cause you the loss of any possibility of error management:

get().and_then(parse)   // What if "parse" fails?
     .and_then(output)

If you use if let, it will look like this:

if let Some(value) = get() {
    if let Some(parsed_value) = parse(value) {
        output(value);
    } else {
        println!("parsing failed");
    }
} else {
    println!("Getting the value failed");
}

Convoluted and hard to read.

if not let

There was a RFC for including something like if !let x = get() { error management }, but it didn't caught on. What nobody online however doesn't seem to mention is that you can create something like this:

let value = if let Some(value) = get() {value} else {
    println!("Couldn't get value!");
    return;
};

let parsed_value = if let Some(pv) = parse(value) {pv} else {
    println!("Couldn't parse value!");
    return;
};

I admit, that looks very convoluted. In another RFC the following syntax was proposed, but postponed for now:

let value = get() else return println!("No value!");  // Not valid

So I guess for now we will have to live with either the convoluted syntax or a lot of lines/indentation.

posted at 14:40  ·  rust  if  let