A struct can have its own static and instance methods (or functions) but are not created within the struct itself. These methods exist in a separate block using impl and they can be either static or instance methods.
How to Create Methods
Consider a struct called Calculator that performs arithmetic through its methods – static or instance. Initially, the struct would be pub struct Calculator {} – without any methods. If we need to add methods to Calculator, we would use impl as follows.
1 2 3 4 5 | pub struct Calculator {} impl Calculator { // Define methods here } |
Impl can also be used to implement traits.
Define Instance Methods
Instance methods exist in the context of a struct instance. Therefore, the codes must first create an instance of a struct to access its methods. For instance methods, we need to refer to its instance using the first parameter. By convention, it’s called &self.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | impl Calculator { pub fn add(&self, val1: i32, val2:i32) -> i32 { val1 + val2 } pub fn subtract(&self, val1: i32, val2:i32) -> i32 { val1 - val2 } pub fn multiple(&self, val1: i32, val2:i32) -> i32 { val1 * val2 } pub fn divide(&self, val1: i32, val2:i32) -> f64 { val1 as f64 / val2 as f64 } } |
The following code snippet runs these methods. It uses a struct expression to create an instance of the struct. Then, it assigns the instance to cal. Finally, it runs the methods using cal.
1 2 3 4 5 6 7 | fn main() { let cal = Calculator{}; println!("{}", cal.add(1,2)); println!("{}", cal.subtract(1,2)); println!("{}", cal.multiple(1,2)); println!("{}", cal.divide(1,2)); } |
Define Static Methods
Static methods do not need struct instances and do not have &self as their first parameter. Consider the following codes.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | impl Calculator { pub fn add(val1: i32, val2:i32) -> i32 { val1 + val2 } pub fn subtract(val1: i32, val2:i32) -> i32 { val1 - val2 } pub fn multiple(val1: i32, val2:i32) -> i32 { val1 * val2 } pub fn divide(val1: i32, val2:i32) -> f64 { val1 as f64 / val2 as f64 } } |
To run these static methods, we need to use the :: (double-colon operator) between struct name and function. We use Calculator to run add and other methods.
1 2 3 4 5 6 | fn main() { println!("{}", Calculator::add(1,2)); println!("{}", Calculator::subtract(1,2)); println!("{}", Calculator::multiple(1,2)); println!("{}", Calculator::divide(1,2)); } |
Run Like The Other – Static or Instance Method
We cannot use instance methods like static methods. Consider the following code snippets.
1 2 3 4 5 6 7 | ... impl Calculator { pub fn add(&self, val1: i32, val2:i32) -> i32 { val1 + val2 } ... } |
This will not work because the method expects the first argument for the &self parameter.
1 2 3 4 | fn main() { let p = Calculator {}; Calculator::add(2, 3); } |
The same thing goes for static methods.
1 2 3 4 5 6 7 | ... impl Calculator { pub fn add(val1: i32, val2:i32) -> i32 { val1 + val2 } ... } |
The codes will fail – error[E0599]: no method named add
found for type Calculator
in the current scope.
1 2 3 4 | fn main() { let p = Calculator {}; p.add(2, 3); } |