Translate

lunes, 27 de noviembre de 2023

Sobrecarga de operadores por medio de traits en Rust


 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 }