¿Cómo implemento Agregar rasgo para una referencia a una estructura?

Hice una Estructura Vector dos elementos y quiero sobrecargar el operador + .

Hice que todas mis funciones y métodos tomaran referencias, en lugar de valores, y quiero que el operador + funcione de la misma manera.

 impl Add for Vector { fn add(&self, other: &Vector) -> Vector { Vector { x: self.x + other.x, y: self.y + other.y, } } } 

Dependiendo de la variación que intente, o tengo problemas de por vida o escribo desajustes. Específicamente, el argumento de &self parece no ser tratado como el tipo correcto.

He visto ejemplos con argumentos de plantilla en impl y Add , pero solo dan como resultado errores diferentes.

Encontré ¿Cómo puede un operador estar sobrecargado para diferentes tipos de RHS y valores devueltos? pero el código en la respuesta no funciona incluso si pongo un use std::ops::Mul; en la cima.

Estoy usando rustc 1.0.0-nightly (ed530d7a3 2015-01-16 22:41:16 +0000)

No aceptaré “solo tiene dos campos, ¿por qué usar una referencia?” Como respuesta; ¿y si quisiera una estructura de 100 elementos? Aceptaré una respuesta que demuestre que incluso con una estructura grande debería pasar el valor, si ese es el caso (aunque no creo que lo sea). Estoy interesado en conocer una buena regla general para el tamaño de la estructura y pasando por valor vs struct, pero esa no es la pregunta actual.

Necesita implementar Add &Vector lugar de Vector .

 impl<'a, 'b> Add<&'b Vector> for &'a Vector { type Output = Vector; fn add(self, other: &'b Vector) -> Vector { Vector { x: self.x + other.x, y: self.y + other.y, } } } 

En su definición, Add::add siempre toma self por valor. Pero las referencias son tipos como cualquier otro 1 , por lo que pueden implementar rasgos también. Cuando se implementa un rasgo en un tipo de referencia, el tipo de self es una referencia; la referencia se pasa por valor Normalmente, pasar el valor en Rust implica transferir la propiedad, pero cuando las referencias se pasan por valor, simplemente se copian (o se vuelven a suscribir / mover si se trata de una referencia mutable), y eso no transfiere la propiedad del referente (porque una referencia no posee su referente en primer lugar). Teniendo en cuenta todo esto, tiene sentido para Add::add (y muchos otros operadores) tomar self por valor: si necesita tomar posesión de los operandos, puede implementar Add on structs / enums directamente, y si no lo hace , puede implementar Add referencias.

Aquí, self es de tipo &'a Vector , porque ese es el tipo que estamos implementando Add on.

Tenga en cuenta que también especifiqué el parámetro de tipo RHS con una vida útil diferente para enfatizar el hecho de que las vidas de los dos parámetros de entrada no están relacionadas.


1 En realidad, los tipos de referencia son especiales porque puedes implementar rasgos para referencias a tipos definidos en tu caja (es decir, si puedes implementar un rasgo para T , entonces también puedes implementarlo para &T ). &mut T y Box tienen el mismo comportamiento, pero eso no es cierto en general para U donde U no está definido en la misma caja.