Sometimes a Rust program creates structs in many places throughout its code. This can lead to duplicate code, and some difficulty with validating how structs are created.
By adding a method that returns Self, we can create a constructor method. This returns an instance of a struct
based on some arguments. We can even validate arguments to ensure program correctness.
For demonstration, this program has a Bird struct
that includes 4 separate fields. The fields are not important, but there are enough of them to make creating Bird structs cumbersome.
struct
by calling from_name
. In from_name
we return Self—a new Bird struct
is returned.from_color
, which is similar to from_name
but validates its argument, and returns a Bird with the specified color.from_color
with an invalid argument, and the program panics. The panic helps ensure programs are correct.struct Bird { name: String, color: String, size: usize, index: usize, } impl Bird { fn from_name(name: &str) -> Self { Bird { name: name.to_string(), color: String::new(), size: usize::MAX, index: usize::MAX, } } fn from_color(color: &str) -> Self { // It is possible to validate arguments within a function. if color != "blue" { panic!("Color is invalid"); } Bird { name: String::new(), color: color.to_string(), size: usize::MAX, index: usize::MAX, } } } fn main() { // Part 1: create Bird struct with just 1 value. let bird1 = Bird::from_name("parrot"); println!("{}", bird1.name); // Part 2: use the from_color constructor. let bird2 = Bird::from_color("blue"); println!("{}", bird2.color); // Part 3: our constructor validates its argument, so this will panic. let bird3 = Bird::from_color("tree"); }parrot blue thread 'main' panicked at src\main.rs:20:13: Color is invalid
It is also possible in Rust to create structs based on existing structs, even const
structs. This can also simplify code that must create many structs.
While Rust does not have special syntax for constructor methods, it does allow methods to return Self. This is done when implementing traits like From as well.