liveBook · Manning

Unwrap

As explained in Rust in Action: Systems programming concepts and techniques

The unwrap method extracts a successful value from a Result or Option and panics when it contains an error or no value.

unwrap extracts the successful value from a Result. For example, it turns Ok(File) into File; when the Result contains Err(String), it crashes the program instead of handling the error. section 3.4.2

Unwrapping a numeric conversion

A conversion returns a Result, so unwrap makes its successful value available for comparison: let b_ = b.try_into().unwrap();. If conversion fails, the program panics. section 2.3.3

Use unwrap with care:

  • Use it in small programs or main functions when an immediate crash is acceptable. section 8.5.3
  • Avoid relying on it in library code when errors may result from conditions outside the caller’s control. section 8.5.3
  • Prefer more sophisticated error handling when program stability matters. section 3.4.2 section 2.3.3
Listing 3.8 Using Result to mark functions liable to filesystem errors
 use rand::prelude::*;                               #1
 
 fn one_in(denominator: u32) -> bool {               #2
   thread_rng().gen_ratio(1, denominator)            #3
 }
 
 #[derive(Debug)]
 struct File {
   name: String,
   data: Vec<u8>,
 }
 
 impl File {
   fn new(name: &str) -> File {
     File {
       name: String::from(name),
      data: Vec::new()
     }                                               #4
   }
 
   fn new_with_data(name: &str, data: &Vec<u8>) -> File {
     let mut f = File::new(name);
     f.data = data.clone();
     f
   }
 
   fn read(
     self: &File,
     save_to: &mut Vec<u8>,
   ) -> Result<usize, String> {                      #5
     let mut tmp = self.data.clone();
     let read_length = tmp.len();
     save_to.reserve(read_length);
     save_to.append(&mut tmp);
     Ok(read_length)                                 #6
   }
 }
 
 fn open(f: File) -> Result<File, String> {
   if one_in(10_000) {                               #7
     let err_msg = String::from("Permission denied");
     return Err(err_msg);
   }
   Ok(f)
 }
 
 fn close(f: File) -> Result<File, String> {
   if one_in(100_000) {                              #8
     let err_msg = String::from("Interrupted by signal!");
     return Err(err_msg);
   }
   Ok(f)
 }
 
 fn main() {
   let f4_data: Vec<u8> = vec![114, 117, 115, 116, 33];
   let mut f4 = File::new_with_data("4.txt", &f4_data);
 
   let mut buffer: Vec<u8> = vec![];
 
   f4 = open(f4).unwrap();                           #9
   let f4_length = f4.read(&mut buffer).unwrap();    #9
   f4 = close(f4).unwrap();                          #9
 
   let text = String::from_utf8_lossy(&buffer);
 
   println!("{:?}", f4);
   println!("{} is {} bytes long", &f4.name, f4_length);
   println!("{}", text);
 }

See unwrap applied to filesystem operations whose functions return Result values. section 3.4.2

How Rust in Action: Systems programming concepts and techniques covers it

How deep it goes
Defines successful extraction and failure by panic, while deferring sophisticated error handling.
Examples
Uses filesystem access and u16-to-i32 conversion as concrete unwrap examples.
What you can do after
Apply via Rust’s unwrap method to extract successful Result values, accepting a panic when the operation fails.
How it connects
Connects Result to error handling, filesystem operations, type conversion, and program stability.

Also explained in

Compare how 5 books explain unwrap →

Related concepts

This explainer was generated by Manning's knowledge graph from the text of Rust in Action: Systems programming concepts and techniques. The section links point to the parts of the book it draws on.