Introduction
Operator overloading lets you define what operators like +, -, *, and == mean for your own types. Rust exposes this through the traits in the std::ops module, so there is no special syntax — overloading an operator is simply implementing the corresponding trait, such as Add for +. This keeps the mechanism consistent with the rest of the trait system rather than being a separate language feature.
Cricket analogy: Just as the DRS review process follows the same appeal mechanism as a normal umpire decision, Rust makes '+' just an ordinary trait call (Add) rather than a special-cased rule only for built-in types.
Syntax
use std::ops::Add;
#[derive(Debug, Clone, Copy)]
struct Point {
x: i32,
y: i32,
}
impl Add for Point {
type Output = Point;
fn add(self, other: Point) -> Point {
Point {
x: self.x + other.x,
y: self.y + other.y,
}
}
}Explanation
Implementing Add for Point defines an associated type Output, which is the result type of the operation, and an add method that the + operator calls under the hood. Once implemented, writing point_a + point_b compiles to point_a.add(point_b). Other operators follow the same pattern: Sub for -, Mul for *, Neg for unary -, Index for [], and PartialEq for ==. Each trait defines the exact method signature you must implement to hook into the operator.
Cricket analogy: Writing battingAvg + strikeRate compiles down to battingAvg.add(strikeRate) under the hood, the same way an analyst's 'combined rating' formula is really just calling a defined scoring method, not built-in magic.
Example
use std::ops::Add;
#[derive(Debug, Clone, Copy)]
struct Point {
x: i32,
y: i32,
}
impl Add for Point {
type Output = Point;
fn add(self, other: Point) -> Point {
Point { x: self.x + other.x, y: self.y + other.y }
}
}
fn main() {
let p1 = Point { x: 1, y: 2 };
let p2 = Point { x: 3, y: 4 };
let p3 = p1 + p2;
println!("{:?}", p3);
}Output
Point { x: 4, y: 6 }Key Takeaways
- Operator overloading in Rust is implemented via traits in std::ops, not dedicated syntax.
impl Add for Pointwithtype Output = Pointlets you use+on Point values.- Other operators map to traits like Sub, Mul, Neg, Index, and PartialEq.
- The
+operator desugars to a call of the trait's method, e.g.add. - You can overload operators between different types by choosing different Output/RHS types.
Practice what you learned
1. Which trait must be implemented to overload the `+` operator in Rust?
2. What does `type Output = Point;` specify inside an `impl Add for Point` block?
3. What does `p1 + p2` desugar to once `Add` is implemented for the type?
4. Which trait would you implement to support the `==` operator on a custom struct?
5. Where do the operator overloading traits like Add, Sub, and Mul live in the standard library?
Was this page helpful?
You May Also Like
Traits in Rust
Traits define shared behavior that types can implement, similar to interfaces in other languages.
Structs in Rust
Structs let you group related values into a single named type with fields you access by name.
Default Trait Implementations in Rust
Trait methods can provide a default body that implementers may use as-is or override with custom behavior.
Generics in Rust
Generics let you write functions, structs, and enums that work over many types while remaining zero-cost at runtime.
Related Reading
Related Study Notes in Programming
Browse all study notesApache Spark Study Notes
Programming · 30 topics
ProgrammingApache Flink Study Notes
Programming · 30 topics
ProgrammingHadoop Study Notes
Programming · 30 topics
ProgrammingSnowflake Study Notes
Programming · 30 topics
ProgrammingApache Airflow Study Notes
Programming · 30 topics
Programmingdbt (Data Build Tool) Study Notes
Programming · 30 topics