Result and the question mark in Rust

Contents
Ok and Err
The ? operator
Convert with map_err
main returns Result

Ok and Err

Result carries either success or failure. Wrap good values in Ok and problem values in Err, and the type signature tells callers that both outcomes exist.

Keep the error side simple at first, such as a short String message, and refine it once the happy path works.

fn check(n: i32) -> Result<i32, String> { if n >= 0 { Ok(n) } else { Err(String::from("negative")) } }

The check function accepts zero and positive numbers. Negative input returns an Err with a short reason instead of a number.

The ? operator

The question mark returns early on Err and unwraps Ok in one character. Place it after a Result call and the error flows to the caller without manual matching.

The enclosing function must also return a Result, since the operator needs a matching channel for the early return.

fn parse_both(a: &str, b: &str) -> Result<i32, std::num::ParseIntError> { Ok(a.parse::<i32>()? + b.parse::<i32>()?) }

Both parses run in one expression. The first failure returns at once, while two successes add up inside Ok.

Convert with map_err

Map_err rewrites the error side while keeping Ok values untouched. It converts a library error into a message type the rest of the program already uses.

Reach for it at boundaries where a low level failure needs a friendlier or unified error value.

fn parse_age(s: &str) -> Result<i32, String> { s.parse::<i32>().map_err(|e| e.to_string()) }

Good input still yields a number, while bad input yields a String message. The caller sees one error type no matter which parse failed inside.

main returns Result

Main may return a Result, which lets the question mark work at the top level. An Err from main prints a short message and exits with a failure code.

This shape fits small tools that read files or parse arguments and can stop on the first error.

fn main() -> Result<(), std::num::ParseIntError> { let n: i32 = "7".parse()?; println!("ok"); Ok(()) }

The parse either fills n or exits through the Err path. Successful runs print a confirmation and finish with an empty Ok.

Next: Strings advanced

Article author: Arthur Isaev

Related articles
Rust
Rust course: zero to hero in 50 lessons
What is Rust and where it runs
Install Rust
cargo new
Your first program
Variables
Numbers
Strings
Booleans
Tuples
Arrays
Vectors
Slices
if and else
match
Loops
Ownership
Borrowing
Lifetimes
Functions
Structs
Enums in Rust
Advanced match in Rust
Option combinators in Rust
Result and the question mark in Rust
Advanced strings in Rust
Vec methods in Rust
HashMaps in Rust
Modules in Rust
Crates and workspaces in Rust
Testing in Rust
Error handling
Traits
Generics
Trait bounds
Closures
Iterators
Smart pointers
Threads
Mutex and Arc
Files
CLI arguments
Environment variables
Diagnostics
Time
Parsing strings
TCP networking
Capstone: wordfreq CLI
Capstone: tiny HTTP server
Modern Rust tour
Hero roadmap: the whole course on one page
Install Rust on Windows 11
Install Rust on Ubuntu
Install Rust on Rocky Linux
Install Rust on macOS
Install Rust on FreeBSD
Rust in Docker
Banner image

Search this site

Channel @aofeed Chat @aofeedchat

Contacts and cooperation:
I recommend our hosting beget.com
Write to info@aredel.com if you:
1. Want to write an article for our site or translate an article into your native language.
2. Want to place thematically relevant ads on the site.
3. Ads on my site pass maximum censorship. If you see an ad block unsuitable for school-age children, shocking or misleading - please contact us by e-mail
4. Found a mistake, inaccuracy, bug, etc. on the site. ... .......
5. Articles can be shared on social media by clicking a network icon: