Do you want your ad here?

Contact us to get your ad seen by thousands of users every day!

[email protected]

The try block in Rust

  • April 09, 2025
  • 1700 Unique Views
  • 3 min read
Table of Contents
The limit of the ? operatorThe verbose alternativeThe try block to the rescueConclusion

I wrote previously about libs for error management in Rust. This week, I want to write about the try block, an experimental feature.

The limit of the ? operator

Please check the above article for a complete refresher on error management in general and the ? operator in particular. In short, ? allows to hook into a function call that returns a Result:

  • If the Result contains a value, it continues normally
  • If it contains an error, it short-circuits and returns the Result to the calling function.
fn add(str1: &str, str2: &str) -> Result<i8, ParseIntError> {
  Ok(str1.parse::<i8>()? + str2.parse::<i8>()?)
}

fn main() {
    print!("{:?}", add("1", "2"));
    print!("{:?}", add("1", "a"));
}

The output is the following:

Ok(3)
Err(ParseIntError { kind: InvalidDigit })

Note that the defining function's signature must return a Result or an Option. The following block doesn't compile:

fn add(str1: &str, str2: &str) -> i8 {
  str1.parse::<i8>()? + str2.parse::<i8>()?
}
the `?` operator can only be used in a function that returns `Result` or `Option`

The verbose alternative

We must manually unwrap to return a non-wrapper type, e.g., i8 instead of Option.

fn add(str1: &str, str2: &str) -> i8 {
  let int1 = str1.parse::<i8>();                  //1
  let int2 = str2.parse::<i8>();                  //1
  if int1.is_err() || int2.is_err() { -1 }        //2-3
  else { int1.unwrap() + int2.unwrap() }          //4
}
  1. Define Result variables
  2. Manually checks if any of the variables contains an error, i.e., the parsing failed
  3. Return a default value since we cannot get a Result. In this case, it's not a great idea, but it's for explanation's sake
  4. Unwrap with confidence

The try block to the rescue

The sample above works but is quite lengthy. The try block is an experimental approach to make it more elegant. It allows "compacting" all the checks for errors in a single block:

#![feature(try_blocks)]                           //1

fn add(str1: &str, str2: &str) -> i8 {
  let result = try {
    let int1 = str1.parse::<i8>();
    let int2 = str2.parse::<i8>();
    int1.unwrap()? + int2.unwrap()?               //2
  };
  if result.is_err() { -1 }                       //3
  else { result.unwrap() }                        //4
}
  1. Enable the experimental feature
  2. Use the ? operator though the defining function doesn't return Result
  3. Check for errors only once
  4. Unwrap confidently

Alas, the code doesn't compile:

the `?` operator can only be applied to values that implement `Try`

i8 doesn't implement Try. Neither i8 nor Try belong to our crate; a custom implementation would require the use of the wrapper-type pattern. Fortunately, a couple of types already implement Try: Result, Option, Poll, and ControlFlow.

fn add(str1: &str, str2: &str) -> i8 {
  let result: Result<i8, ParseIntError> = try {   //1
    str1.parse::<i8>()? + str2.parse::<i8>()?     //2
  };
  if result.is_err() { -1 }
  else { result.unwrap() }
}
  1. The compiler cannot infer the type
  2. Using ? on Result inside the try block is now allowed

Conclusion

I learned about the try block in Java over twenty years ago. Java needs it because exceptions are at the root of its error-handling system; Rust doesn't because it uses Functional Programming for its error handling - mainly Result.

The ? operator builds upon the Result type to allow short-circuiting in functions that return Result themselves. If the function doesn't, you need a lot of boilerplate code. The experimental try block relieves some of it.

To go further:


Originally published at A Java Geek on April 21st, 2024

Achieving High Throughput Without Sacrificing Latency

Low latency coding techniques are designed to keep a processor core as busy as possible, executing at its full potential and so getting work done as quickly as possible.

AI-powered Chat Application using IBM watsonx.ai and Spring AI

Table of Contents PricingIBM watsonx.aiCreating IBM watsonx.ai Chat-based ApplicationPrerequisitesConfigurationsChatbotChat ApplicationBasic ChatStreaming Chat Generative Artificial Intelligence (Gen AI) disrupted enterprises with the introduction of GPT-4 foundation model by Open AI in the late 2022 to early 2023 triggering big tech to …

Apple Silicon with Zulu OpenJDK and IntelliJ IDEA

Azul has been leading the OpenJDK community effort (JEP 391) initiated in August 2020 to add support for Apple Silicon, Arm-based Macs, in future versions of OpenJDK.

In addition to targeting future Java versions, such as Java 16 via JEP 391, Azul has made OpenJDK builds of currently popular Java versions, including Zulu builds of OpenJDK 8, 11, and 13, as well as 16-ea, widely available for use on Apple Silicon, Arm-based Macs.

Automatic WildFly Clustering in Managed Domain Mode and Scaling inside Containers

How to extend WildFly from standalone server to cluster in managed domain mode inside containers for running cloud-native scalable applications?

There is no need to rebuild the whole application architecture in order to gain the required outcome from both managed domain mode and container technology.

Migration of legacy projects from VMs to micro clusters with system containers is not that painful at all.

It brings a “rich taste” of flexibility and efficiency for increasing competitive advantage.

Available Now – gRPC for Apache Cassandra

General availability of a gRPC API for Apache Cassandra to leverage a powerful database in combination with a microservices-oriented API.

Do you want your ad here?

Contact us to get your ad seen by thousands of users every day!

[email protected]

Comments (0)

Highlight your code snippets using [code lang="language name"] shortcode. Just insert your code between opening and closing tag: [code lang="java"] code [/code]. Or specify another language.

No comments yet. Be the first.

Subscribe to foojay updates:

https://foojay.io/feed/
Copied to the clipboard