development-programming-language-rust-traits.html
* created: 2025-07-17T12:02
* modified: 2025-10-15T11:19
title
Rust Traits
description
Traits are used to share functionality over multiple types. Furthermore we can define trait bounds that check if a type implements a certain trait and therefore has certain properties.
What are Traits?
Common Traits for Types
The following traits should generally be implemented by most of the types in a API:
Debug, Clone
Send, Sync, and Unpin
PartialEq, PartialOrd, Hash, Eq and Ord
Serialize and Deserialize (as opt in)
When using wrapper types the following traits should be implemented in addition: Deref, AsRef, From/Into<InnerType>, Borrow.
Exception
Copy: People generally don't expect types to implement Copy because it changes the move semantics of a given type, which might surprise user. It is often advisable to rely on Clone instead to explicitly create a a new copy. In addition Copy is highly restrictive and could result in a breaking change if a type has to rely on something like String further done the line.
dyn vs impl
Dynamic dispatch (dyn) allows for calling methods on trait objects at runtime, enabling polymorphism. If a function fn some(&dyn Trait) { ... } is called, it expects the input to be a pointer to a trait object (because the size is unknown during compile time). If mutability is needed use a Box<dyn Trait>.
Note: This is achieved using "fat pointers," which contain a pointer to the data and a pointer to a vtable that holds the method implementations for the specific type.
impl on the other hand uses static dispatch, which generates a separate version of the function at compile time for each concrete type used. This is referred to as monomorphization.