traits

Send and Sync traits for safe concurrency guarantees

Send means a type can be transferred across thread boundaries. Sync means a type can be shared between threads (&T is Send). Most types are Send + Sync; exceptions include Rc (not Send) and RefCell (not Sync). The compiler uses these marker traits

impl Trait for opaque return types

impl Trait in return position lets you return a type that implements a trait without naming it. This is useful for closures, iterators, or futures where the concrete type is complex or unnameable. The caller only knows it implements the trait. I use i

Deref and DerefMut for smart pointer ergonomics

Implementing Deref lets your type automatically coerce to its target type. For example, Box<T> derefs to T, and String derefs to str. This enables method calls and conversions without explicit unwrapping. I implement Deref for wrapper types and

From and Into for type conversions

The From and Into traits provide a standard way to convert between types. Implementing From<T> for your type automatically provides Into<T> via a blanket implementation. I use From for infallible conversions (like String::from("hello")) an

std::fmt::Display for user-facing string representations

Implementing Display lets your types be formatted with {} in format strings. It's for user-facing output, unlike Debug which is for developers. I implement Display for error types, domain models, and anything that might be printed. The trait requires

Associated types in traits for cleaner generics

Associated types let a trait declare a type that implementors must define. This is cleaner than adding a generic parameter to the trait. For example, Iterator has an associated type Item rather than being Iterator<Item>. I use associated types w

Trait bounds for generic functions with behavior constraints

Traits define shared behavior, and trait bounds let you write generic functions that work with any type implementing a trait. The syntax T: Display means "T must implement Display." This is similar to interfaces in other languages but more powerful: y

AsRef and AsMut for flexible function parameters

AsRef<T> is a trait for cheap reference-to-reference conversion. It's commonly used in function parameters to accept multiple types. For example, a function taking impl AsRef<Path> can accept &Path, PathBuf, &str, or String. This i

Default trait for sensible zero values

The Default trait provides a default value for a type, useful for builder patterns, config merging, and initialization. I derive Default on structs where zero/empty is meaningful. For custom logic, implement it manually. Default::default() is the stan

Derive macros for automatic trait implementations

Rust's #[derive] attribute auto-generates trait implementations for common traits like Debug, Clone, PartialEq, and Serialize. This eliminates boilerplate and ensures consistency. For example, #[derive(Debug)] generates a debug formatter that prints a

Drop trait for custom cleanup logic

The Drop trait runs when a value goes out of scope, similar to destructors in C++. I implement Drop for resource handles: closing file descriptors, releasing locks, or logging cleanup. The drop method takes &mut self and can't fail (no Result). Ru

Sized trait and ?Sized for dynamically-sized types

Most types in Rust are Sized (known size at compile time), which is an auto trait. Some types like str or [T] are !Sized (dynamically-sized types, DSTs). To work with DSTs, use &T or Box<T>. In generic code, T: Sized is the default bound. To