What are Rust Result's variants and how does the compiler enforce handling?
This tests Rust's explicit error model. A strong answer names Ok(T) and Err(E), explains must_use warns when Results are ignored, and notes pattern matching or ? is required to extract values.
WHAT THIS TESTS: This question checks whether you understand that Rust treats error handling as a first-class type system concern rather than an afterthought. The interviewer wants to see that you know Result is an algebraic data type whose variants encode success and failure explicitly, and that you understand how the compiler nudges developers toward handling errors rather than letting them slip through.
A GOOD ANSWER COVERS: First, name the two variants exactly: Ok(T), which wraps a successful return value of type T, and Err(E), which wraps an error value of type E. Second, explain the must_use attribute attached to Result, which causes the compiler to emit a warning whenever a Result is created and then dropped without being pattern matched, unwrapped, propagated with the question mark operator, or otherwise inspected. Third, describe the mechanical consequence of Result being an enum: you cannot directly use the T inside without first deciding what to do in the Err case, whether via match, if let, while let, or the question mark operator in a function that returns a compatible Result. Fourth, contrast this with exceptions or sentinel values in other languages to show you appreciate the design philosophy of making failure visible at the API boundary.
COMMON WRONG ANSWERS: Calling Result an option type or saying it can be null. Claiming that Rust automatically propagates or logs errors without programmer action. Forgetting to mention must_use and only describing the two variants. Saying that unwrap is the idiomatic way to handle errors in production code. Asserting that the compiler forces you to handle errors via hard errors rather than warnings; must_use is a warning by default, though it can be denied.
LIKELY FOLLOW-UPS: How does the question mark operator desugar, and what trait bounds does it require? When would you use Result versus Option, and how do they interact? What is the difference between unwrap, expect, and unwrap_or? How does Result compose with iterators or async code? What happens if you ignore a Result in a main function or a Drop implementation?
ONE CONCRETE EXAMPLE: Consider the std::io::Write trait method write_all, which returns Result with unit and io::Error. If you call file.write_all with byte string data and do nothing with the return value, the compiler issues an unused_must_use warning because Result is annotated with must_use. To satisfy the compiler you must either handle the error with a match, assert success with expect, or propagate it with the question mark operator. This makes it nearly impossible to accidentally ignore a failed disk write.
Read the original → doc.rust-lang.org
Get five bites like this every day.
Tezvyn delivers a daily feed of 60-second tech bites with quizzes to lock in what you learn.