Rust Tips and Tricks #PartOne
Dan Mugisho M.
Posted on April 8, 2023
Rust is a programming language that has gained a reputation for its exceptional qualities in terms of reliability, speed, and overall enjoyment for the programmer. However, it is important to keep in mind that Rust is also recognized as a language with a relatively high level of complexity.
As programmers, when we start using a new language, we tend to apply the concepts and techniques we have learned from our previous language experiences. Initially, we may not be familiar with the idiomatic way of writing code, nor the efficient shortcuts that the new language offers. Nevertheless, we manage to make progress by experimenting with the code until it runs and compiles.
This is perfectly natural. Over time, by seeing other people’s code, we learn, we adapt, and we write better code. This post tries to speed up that process by showing you some of the Rust shorthands I have discovered so far.
Avoid unnecessary clones
When a variable is cloned using the .clone() method, its data is duplicated, which requires additional resources. As a result, clones typically have a detrimental impact on performance and should be used sparingly. In many cases, it is possible to pass references to the same variables to different functions, eliminating the need for cloning. For example :
Using Cow as return type
Occasionally, you may need to write methods that accept a string slice (&str) as input and possibly return either an altered version of the input or the original string.
In such situations, the Cow type can prove to be useful since it allows you to avoid allocating new memory unnecessarily. By using Cow, you can modify the input string when needed, but if no changes are required, the original string can be returned without incurring any additional memory allocation costs.
Enum size is bounded by the largest member
To ensure that an Enum can accommodate its largest variant, its size is determined accordingly. To optimize memory usage, it is advisable to keep the variants within an Enum of similar sizes. However, if necessary, larger variants can be boxed. Consider this example :
Using dbg!() macro instead of println!()
The dbg macro can be used to print the value as well as the source code of an express to stderr. Example usage:
The above code will print :
2
[src/main.rs:5] var1 = 2
Output: [src/main.rs:6] var1 * 2 = 4
Crossbeam channels instead of the standard ones
The crossbeam crate offers a powerful alternative to standard channels with support for the Select operation, timeouts, and more.
Customize and chain Panic handlers
Panic handlers (called hooks) can be overridden and chained, which becomes particularly useful when setting up custom error reporting and logging for your application.
Output :
custom error reporting logic panicked at 'test', src/main.rs:20:5
custom logging logic panicked at 'test', src/main.rs:20:5
The standard swap function
The swap function allows you to directly swap two variables without needing to create a temporary variable.
Use impl Trait when working with Closures
When passing a closure to a function, it is generally better to use the “impl Fn/FnOnce/FnMut” approach instead of a generic one. This approach, also known as “impl Trait,” helps keep the function’s signature uncluttered. In more complex scenarios, however, you may need to box the closure with “Box” to make it work. It is essential to keep in mind that boxing a closure can introduce additional overhead, which may be undesirable in some cases.
Therefore, it is important to weigh the benefits and drawbacks of each approach and choose the one that best suits your requirements.
Output :
setting up...
Action!
tearing down...
Clippy and rustfmt
They are two of my favorite Rust tools. If you haven’t tried them yet, I highly recommend giving them a try. Clippy can detect various lints in your code and guide you towards writing more idiomatic code. To install Clippy, simply run rustup component add clippy, and to run it within your workspace, execute cargo clippy. For more details, visit Clippy’s GitHub repository.
Rustfmt is a tool that formats Rust code in compliance with style guidelines. Its name precisely reflects its purpose. To install rustfmt, you can run rustup component add rustfmt. Once installed, you can execute cargo fmt to format Rust code in your workspace. If you require further information, you can visit rustfmt’s GitHub repository.
Simplify Your Rust Error Handling with “thiserror” and “anyhow”
When it comes to handling errors in Rust, it is often best to use the “thiserror” and “anyhow” crates for an idiomatic approach. “Thiserror” is useful when the consumer of the error needs to take action based on specific error conditions.
CONCLUSION
Rust is a programming language with immense potential, and it has something new to offer every day. I hope that this post has provided you with valuable insights into Rust and helped you learn something new. If you have any questions or want to share your thoughts, please feel free to leave a comment or reach out to me. Let’s continue to explore the vast possibilities of Rust together.
☞ Follow me on Twitter & Linkedin
☞ Kindly subscribe for my upcoming articles
Posted on April 8, 2023
Join Our Newsletter. No Spam, Only the good stuff.
Sign up to receive the latest update from our blog.
Related
January 14, 2024