What is unwrap in Rust, and what is it used for?

RustError Handling

Rust Problem Overview


I have this code that uses .unwrap():

fn main() {
    let paths = std::fs::read_dir("/home/user").unwrap();

    for path in paths {
        println!("Name: {}", path.unwrap().path().display());
        
    }
}

After looking at the definition of unwrap,

pub fn unwrap(self) -> T {
  match self {
        Ok(t) => t,
        Err(e) => unwrap_failed("called `Result::unwrap()` on an `Err` value", e),
    }
}

And the signature of read_dir

pub fn read_dir<P: AsRef<Path>>(path: P) -> io::Result<ReadDir>

Am I correct in understanding that unwrap returns the T type that is passed in Result?

Rust Solutions


Solution 1 - Rust

In Rust, when you have an operation that may either return a T or fail, you will have a value of type Result<T,E> or Option<T> (E will be the error condition in case of an interesting error).

The function unwrap(self) -> T will give you the embedded T if there is one. If instead there is not a T but an E or None then it will panic.

It is best used when you are positively sure that you don't have an error. If that is not the case usually it is better either pattern-match the error or use the try! macro ? operator to forward the error.

In your example, the call to read_dir() returns a io::Result<ReadDir> because opening the directory might fail. And iterating the opened directory returns multiple values of type io::Result<DirEntry> because reading the directory might also fail.

With try! ? it would be something like this:

fn try_main() -> std::io::Result<()> {
    let entries = std::fs::read_dir("/home/user")?;

    for entry in entries {
        println!("Name: {}", entry?.path().display());

    }
    Ok(())
}

fn main() {
    let res = try_main();
    
    if let Err(e) = res {
        println!("Error: {}", e);
    }
}

Look how every error case is checked.

(Updated to use ? instead of try!(). The macro still works, but the ? is preferred for new code).

Solution 2 - Rust

The problem is that reading a line from a file produces a potential error type. The type is

       Result<String,std::io::Error>

Result is an enum. There are two potential values in the Result, they are used for error handling and management. The first value is Err. If Err is populated, there was an error in the function that was called. The other potential selection is Ok. Ok contains a value.

enum Result<T, E> {
    Ok(T),
    Err(E),
}

Enum is a complex type, rather than a single value. To get the value we are looking for, we use unwrap() to unwrap the value.

unwrap() is used here to handle the errors quickly. It can be used on any function that returns Result or Option (Option is also enum). If the function returns an Ok(value), you will get the value. If the function returns an Err(error), the program will panic.

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionAngel AngelView Question on Stackoverflow
Solution 1 - RustrodrigoView Answer on Stackoverflow
Solution 2 - RustYilmazView Answer on Stackoverflow