ib RustBite Idioms
about
05/19/2022
RustBites - Idiomatic Rust
Code Repository Code Examples Rust Bites Repo

Rust Bite - Idiomatic Rust

writing rustacean code

Idiomatic code is written in a style respected by the language community. It's purpose is to foster clarity, avoid unnecessary loss of performance or increase in complexity, and provide a common format that most developers favor. Rust has a great set of tools to help you write idiomatic code.

1.0  An Example:

Prefer this code let demo1: Option = Some("I am here".to_string()); let demo2: Option = None; /* ref avoids moving Some contents to s */ if let Some(ref s) = demo1 { print!("\n Option contained {:?}", s); } else { print!("\n Option is None"); } Over this code let demo1: Option = Some("I am here".to_string()); let demo2: Option = None; if demo1.is_some() { print!( "\n Option contained {:?}", demo1.unwrap() ); } else { print!("\n Option is None"); }
playground demo The code on the left uses "if let" to match demo1 with Option's Some(s) item. The match, if it succeeds, implicitly destructures demo1 and binds it's string literal to the name s. The Ref prefix causes the binding to use a reference to the inner value. So demo1 remains valid. The code on the right uses is_some() to test for the item type, but does not destructure. The print statement then must unwrap() the value, which moves it out of the Some item. So demo1 is no longer valid. Writing code with explicit unwrap()s indicates that your code is probably not idiomatic. The "if let" matching style avoids this and is widely used in the Rust community's code.

2.0  Clippy Tool:

Clippy is a style checker that cargo can invoke with:
cargo clippy
When invoked it either returns silently or emits one or more warnings, like that shown below. Clippy is a very useful tool, not only to help you render your code in a more idiomatic way, but also detect code that may not function as you expect.
It does this by comparing your code against a large set of "lints", which we will look at briefly in the next section. Here's an example:
Non-idiomatic let mut iter = v.iter(); if let Some(e) = iter.nth(0) { print!("\n first elem: {} has type: {}", e, type_is(&e)); } Clippy message - generated by running clippy in Rust playground for code above warning: called `.nth(0)` on a `std::iter::Iterator`, when `.next()` is equivalent --> src/main.rs:39:22 | 39 | if let Some(e) = iter.nth(0) { | ^^^^^^^^^^^ help: try calling `.next()` instead of `.nth(0)`: `iter.next()` | = note: `#[warn(clippy::iter_nth_zero)]` on by default = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#iter_nth_zero
playground demo , Clippy lint Rust provides a very large set of language and standard library facilities - so large that it is hard to know when to use them or even to know they exist. Clippy helps with that by suggesting changes to your code that uses the most effective facility.

3.0  Clippy Lints:

The clippy tool analyzes Rust code for compliance with a large set of rules (259). It divides them into categories, below, which you can enable or not, e.g., insert, at top of the code, #![allow(clippy::nursery)]. That declaration eliminates warnings about lints that have been recently added and may not be stable. In place of allow either warn or deny can be used.
* `clippy` (everything that has no false positives) * `clippy_pedantic` (everything) * `clippy_nursery` (new lints that aren't quite ready yet) * `clippy_style` (code that should be written in a more idiomatic way) * `clippy_complexity` (code that does something simple but in a complex way) * `clippy_perf` (code that can be written in a faster way) * `clippy_cargo` (checks against the cargo manifest) * **`clippy_correctness`** (code that is just outright wrong or very very useless)
clippy crate README.md The clippy crate repository has an index of all the lints with explanitory comments. You can view specific categories using check-boxes: Clippy Lints Clippy is a great tool for polishing code before you publish. It also helps you explore areas where your skills need some work.

4.0  Rust API Guidelines:

The Rust api-guidelines is an ebook with table of contents:
  • Naming conventions
  • Interoperability
  • Macros
  • Documentation
  • Predictability
  • Flexibility
  • Type Safety
  • Dependability
  • Future proofing
  • Necessities
You can find most of the Rust idioms here, in text form with examples. That isn't as easy to use as clippy, but the explanations are, in many cases, deeper and more satisfying. You can use clippy immediately, as you begin Rust, without knowing much. Clippy is a great teacher, citing everything it thinks could be better, and giving small explanations. But you may have to look further, like these guide-lines, to understand the motivation behind some clippy warnings.

4.0  Final Thought:

The most difficult part of writing idiomatic Rust code is to use the Rust language and library facilities rather than building your own facilities, wherever that is practical. It's difficult because there are so many excellent facilities provided by the language and libraries. How do you do that???
  1. Clippy helps, but that is limited by the fact that clippy can't analyze your code and partition it into parts that map onto existing facilities.
  2. Reading language and library documentation is a good start. It's well written, clear, and thoroughly commented.
  3. Subscribe to "This Week in Rust". That has blogs, comments, and questions with answers from the Rust developers.
  4. Get a copy of Programming Rust by Jim Blandy and Jason Orendorff. It's my favorite.
But most important: write lots of code, read it critically, and edit.
  Next Prev Pages Sections About Keys