🦀 Rust Master Class - Chapter 19: Type Coercion
Speed dating. Three minutes, a stranger, no expectations. But we clicked. &String becomes &str — two different types, suddenly compatible. The compiler sees it before you do.
Coercion in Rust refers to the implicit conversion of one type into another . Unlike explicit casting (using the `as` keyword), coercion happens automatically in specific "coercion sites" like function arguments, `let` bindings, and return values.
1. Deref Coercion
This is the most common form of coercion. If a type T implements the Deref trait, a reference to T (&T) can be implicitly converted to a reference of its target type U (&U) ``.
- Key Concept: A common example is converting
&Stringto&stror&Vec<T>to&[T]``. - DerefMut: This allows for mutable coercion, such as converting
&mut Stringto&mut str``.
Code Example:
`rust
fn accept_str(s: &str) {
// Output to console
println!("Received: {s}");
}
fn main() {
// Create a new variable
let s = String::from("Some String");
accept_str(&s); // &String is coerced to &str via Deref
}
`
2. Reference Coercion
Rust allows a mutable reference (&mut T) to be coerced into an immutable reference (&T) . However, the reverse (`&T` to `&mut T`) is **not allowed** as it would violate memory safety rules .
Code Example:
`rust
fn accepts_immut_ref(s: &String) {
// Output to console
println!("{s}");
}
fn main() {
// Create a mutable variable
let mut s = String::from("Some String");
// Create a mutable variable
let mut_ref = &mut s;
accepts_immut_ref(mut_ref); // &mut String is coerced to &String
}
`
3. Function Item Coercion
Every function in Rust has its own unique "function item type" . These can be implicitly coerced into a **function pointer (`fn`)** if the signatures match. This is useful for passing specific functions as arguments to more general handlers .
Code Example:
`rust
fn email_notification(user: &str) { /* ... */ }
fn notify_user(method: fn(&str), s: &str) { method(s); }
fn main() {
// email_notification (item type) coerced to fn(&str) (pointer)
notify_user(email_notification, "Alice");
}
`
4. Trait Object Coercion
A reference to a concrete type &T can be coerced into a trait object &dyn Trait, provided that T implements the specified Trait . This reduces code duplication by allowing one function to handle any type that satisfies a trait requirement .
5. Transitivity and Chaining
Coercion is transitive: if type A can be coerced to B, and B can be coerced to C, then Rust can coerce A directly to C ``.
Code Example:
struct Book { name: String }
impl Deref for Book {
type Target = String;
fn deref(&self) -> &Self::Target { &self.name }
}
// Output to console
fn print_str(s: &str) { println!("{}", s); }
fn main() {
// Create a new variable
let my_book = Book { name: String::from("Rust") };
print_str(&my_book); // &Book -> &String -> &str
}
6. Least Upper Bound Coercion
In contexts with multiple branches, such as an if/else expression or match arms, Rust attempts to find a "least upper bound" type that all branches can coerce to ``.
Code Example:
`rust
// Create a new variable
let condition = true;
// Create a new variable
let output: &str = if condition {
// Allocate a new String on the heap
&String::from("Welcome") // &String coerces to &str
} else {
"World" // already &str
};
`
7. Subtyping and Variance
While Rust does not have traditional class inheritance, it uses subtyping for lifetimes ``.
- Covariance: A reference with a longer lifetime (
&'static str) is a subtype of a shorter one (&'a str) and can be coerced into it ``. - Contravariance: This applies to function arguments; a function that handles any lifetime can be coerced to one that handles a specific, longer lifetime ``.
📖 Download the full PDF: https://drive.google.com/file/d/1ul-u10jUFwMkSMuica69QpEZ4Qpqup2E/view?usp=sharing
Part 19 of the Rust Master Class series — STEM EdTech | Automation Consulting | Rust Tutoring
RustLang #Programming #LearnToCode #STEM #EdTech
📚 Practice Resources
GitHub Repository: https://github.com/PacktPublishing/Rust-Programming-Master-Class-from-Beginner-to-Expert
Try it yourself: https://play.rust-lang.org/
Run the code from this chapter in the Rust playground, then clone the repo to continue your Rust journey!
Part 19 of the Rust Master Class series — STEM EdTech | Automation Consulting | Rust Tutoring
Top comments (0)