Generics & Traits
By using Generics and Traits we can leverage their combined power to write efficient, reusable, and type-safe code.
Generics
Generics used to create definitions for items like function signatures or structs, which we can then use with many different concrete data types.
So instead of writing separate implementations for each type, you define a generic type that can be substituted with concrete types when the code is used.
Represented by angle brackets (
<>
) and often denoted byT
,U
, or other descriptive names.Generics in Rust are resolved at compile time, ensuring that invalid types cannot be used.
Rust generates optimized code for each concrete type used with a generic at compile time, avoiding runtime overhead.
Generic Functions
Functions can use generics to operate on multiple types.
Generic Structs
Structs can hold values of any type using generics.
Generic Enums
Enums can also use generics, as seen with Option or Result.
Traits
A trait is similar to an interface in other programming languages.
It defines a set of methods that a type must implement, allowing you to specify what functionality a type provides without dictating how it provides it.
Implementing a trait on a type is similar to implementing regular methods.
The difference is that after
impl
, we put the trait name we want to implement, then use thefor
keyword, and then specify the name of the type we want to implement the trait for.Traits can provide default method implementations that types can override.
The
impl Trait
syntax works for straightforward cases but is actually syntax sugar for a longer form known as a trait bound.We can also specify more than one trait bound using
+
syntax.
Defining a Trait
A trait defines methods that other types can implement.
Implementing a Trait
Implementing a trait similar like implementing method by put the trait name after
impl
and then specify the type afterfor
.
Default Implementation
Traits can provide default method implementations that types can override.
Traits as Parameters
Traits can be used as parameters using
impl Trait
syntax.The
impl Trait
syntax works for straightforward cases but is actually syntax sugar for a longer form known as a trait bound; it looks like this:We also can have multiple parameters that implement a trait.
For example this function have two parameters that implement Summary:
We can also do it using generics.
But in the example below the generic type
T
specified as the type of theitem1
anditem2
parameters constrains the function such that the concrete type of the value passed as an argument foritem1
anditem2
must be the same.We can also use the impl Trait syntax in the return position to return a value of some type that implements a trait.
Specifying Multiple Trait Bounds
We can also specify more than one trait bound using
+
syntax.The
+
syntax is also valid with trait bounds on generic types.
Generic Traits
Traits can also be generic, allowing them to operate over a range of types.
Extending Existing Traits
We can extend existing traits by combining them or adding additional behavior.
References
Last updated