trait, impl Examples (dyn Keyword)Use the trait and impl keywords to add a function to multiple structs, and then call it from the trait type.
This page was last reviewed on Mar 15, 2023.
Trait. 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.
Trait and impl. 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.
An example. 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.
Note To implement the Animal trait for Bird structs, we specify a get_weight function that is based on the Bird's feather count.
Note 2 For the snake implementation of Animal, we base the get_weight function on the number of scales the snake has.
Info The print_weight function receives an Animal trait instance, and we must use the "dyn" keyword to specify this is a trait.
Finally The program instantiates the Bird and Snake, and uses the Animal trait to access their 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); }
Impl example. An impl block can be used without complex features like dyn or traits. We can use impl to specify "instance methods" on a struct.
Tip This can make code more readable and modular. Fewer types may need to be imported into new Rust files.
struct Example { colors: usize, } impl Example { fn test(&self) { // Print colors from self. println!("Colors = {}", self.colors); } } fn main() { let ex = Example { colors: 15 }; // Call test function. ex.test(); }
Colors = 15
Impl performance. In some programming languages, calling a function on a type instance may be slower than a top-level function. We test this issue in Rust with impl.
Version 1 This version of the code invokes the test_value() function that is not part of an impl block (a top-level function).
Version 2 Here we call an impl version of the test_value() function that does the same thing.
Result No significant performance difference was found. It is equally efficient to call functions in impl blocks.
use std::time::*; fn test_value(value: &str) { if value != "bird" { panic!("ERROR"); } } struct Example { value: String, } impl Example { fn test_value(&self) { if self.value != "bird" { panic!("ERROR"); } } } fn main() { if let Ok(max) = "100000000".parse::<usize>() { let value = "bird".to_owned(); let ex = Example { value: "bird".to_owned(), }; // Version 1: test with top-level function. let t0 = Instant::now(); for _ in 0..max { test_value(&value); } println!("{} ms", t0.elapsed().as_millis()); // Version 2: test with function in impl block. let t1 = Instant::now(); for _ in 0..max { ex.test_value(); } println!("{} ms", t1.elapsed().as_millis()); } }
34 ms test_value() 33 ms ex.text_value()
Language notes. 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.
A summary. 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.
Dot Net Perls is a collection of tested code examples. Pages are continually updated to stay current, with code correctness a top priority.
Sam Allen is passionate about computer languages. In the past, his work has been recommended by Apple and Microsoft and he has studied computers at a selective university in the United States.
This page was last updated on Mar 15, 2023 (new example).
© 2007-2023 Sam Allen.