La sobrecarga del operador se implementa mediante rasgos en std::ops:
#[derive(Debug, Copy, Clone)]
struct Point { x: i32, y: i32 }
impl std::ops::Add for Point {
type Output = Self;
fn add(self, other: Self) -> Self {
Self {x: self.x + other.x, y: self.y + other.y}
}
}
fn main() {
let p1 = Point { x: 10, y: 20 };
let p2 = Point { x: 100, y: 200 };
println!("{:?} + {:?} = {:?}", p1, p2, p1 + p2);
}
Si lo ejecutamos :
cargo run main.rs
Compiling hello_cargo v0.1.0
Finished dev [unoptimized + debuginfo] target(s) in 0.58s
Running `target/debug/hello_cargo main.rs`
Point { x: 10, y: 20 } + Point { x: 100, y: 200 } = Point { x: 110, y: 220 }
Podrías implementar Add para &Point. Si el tipo T para el cual está sobrecargando el operador no implementa Copy, debería considerar sobrecargar también el operador para &T. Esto evita clonaciones innecesarias.
Se podría implementar Add para dos tipos diferentes, p. impl Add<(i32, i32)> for Point agregaría una tupla a un Point.
Sería así :
impl std::ops::Add<(i32, i32)> for Point {
type Output = Self;
fn add(self, other: (i32, i32)) -> Self {
Self {x: self.x + other.0, y: self.y + other.1}
}
}
fn main() {
let p1 = Point { x: 10, y: 20 };
let tuple= (100, 200);
println!("{:?} + {:?} = {:?}", p1, tuple, p1 + tuple);
}
Y la salida va a ser :
Point { x: 10, y: 20 } + (100, 200) = Point { x: 110, y: 220 }