Often a Rust program needs the concept of shared features or an interface
. Multiple structs have the same feature, and need to be used in a unified way.
In Rust, we can have interfaces that are shared between multiple structs by using the trait
-keyword. With impl
, we indicate how those traits are implemented.
Consider this example Rust program—we have an Animal trait, and it is shared between the Bird and Snake structs. On the Animal trait, we get the get_weight
function.
get_weight
function that is based on the Bird's feather count.get_weight
function on the number of scales the snake has.print_weight
function receives an Animal trait instance, and we must use the "dyn" keyword to specify this is a trait.get_weight
functions in print_weight
.trait Animal { fn get_weight(&self) -> u32; } struct Bird { feathers: u32 } impl Animal for Bird { fn get_weight(&self) -> u32 { self.feathers * 2 } } struct Snake { scales: u32 } impl Animal for Snake { fn get_weight(&self) -> u32 { self.scales * 15 } } fn print_weight(arg: &dyn Animal) { // Use Animal trait. println!("WEIGHT: {}", arg.get_weight()); } fn main() { // Create Bird and Snake, use Animal trait. let bird = Bird { feathers: 100 }; print_weight(&bird); let snake = Snake { scales: 50 }; print_weight(&snake); }WEIGHT: 200 WEIGHT: 750
In other programming languages (like C#) the trait
-keyword is most similar to an interface
. Traits can be used to implement features of object-oriented programming.
With traits, we create rules about how structs can be used in a unified way. So we can call a specific function on multiple struct
types—this can make code clearer and more correct.