It’s possible in Rust to conditionally implement methods and traits based on the traits implemented by a type’s own type parameters. While this is used extensively in Rust’s standard library, it’s not necessarily obvious that this is possible. In this article I’ll break down what the pattern is, give some examples of its use in the standard library to show why it’s valuable, and explain when you…
Rust supports a number of type coercions, which implicitly convert one type to another. As in any language with coercion, there is a trade-off made between clarity when reading and ease of writing. While disagreement may be had about whether Rust’s list of supported coercions is best, there is value in learning the coercions available, as some are central to functioning or idiomatic Rust code. In…
You may not know this, but it’s possible to give names to your lifetimes which are longer than a single character! Effectively naming your lifetimes can help improve code clarity in several scenarios, which this post describes in detail.
Trait objects are Rust’s usual mechanism for dynamic dispatch, and when they work they’re wonderful, but many Rust programmers have struggled with the question of when a trait can become a trait object, and what to do when a trait they’re using can’t. This post describes several options for handling an inability to create a trait object, discusses their trade-offs, and describes why the trait…
Rust functions are surprisingly diverse, sitting at the intersection of multiple language features which may take time to understand. In this post, we’ll walk through those features and explain how they appear in function signatures, so you can be well-equipped to understand functions you see in the wild, or identify the best way to write the functions you need in your own code.
Steve Klabnik recently wrote about whether out parameters are idiomatic in Rust. The post ends by showing a snippet of code: a generic function, with a non-generic function inside of it which contains the actual implementation. Steve says this pattern may warrant its own post, so here is that post, where I’ll explain why this inner function is useful, discuss the trade-offs of doing it, and…
Rust gets a lot of first impression posts. For people in the community, reading those posts can often be frustrating, with factual errors leaving people concerned that others will get the wrong impression. For people outside the community, they may be unsure of how much said is true, or how to read these posts effectively. In this post, I outline how I think about first impression posts, and why I…
Foreign Function Interfaces (FFI) are a core mechanism for enabling integration of new languages into existing codebases or building on existing libraries. That said, the term “FFI” is often overloaded in ways that may be unclear or ambiguous, and the area can seem overwhelming to approach. In this post, I explain the two “directions” of FFI, some patterns for how FFI in each direction is handled…
Rust has two major mechanisms for delegating logic: enums and trait objects, and it may be unclear when to use one or the other. In this post, I will walk through how each works, what the tradeoffs are, and how to choose the right option for your code.
The Rust compiler ships with a number of useful lints on by default, and many use Clippy to provide additional lints. It’s less well known that the Rust compiler ships with some useful lints which are set to allow by default, meaning they don’t generate warnings. In this post, I’ll explain what each of these lints does, and why it might be useful.