I'm trying to create a trait with some default method implementation. One of the methods has to take an instance of the same type and perform some computations.
Here is the simplistic example of what I'm trying to achieve:
struct A {
val: f32,
}
trait S {
fn val(&self) -> f32;
fn add(&self, other: &Self) -> f32 {
add(&self, other)
}
}
impl S for A {
fn val(&self) -> f32 {
self.val
}
}
fn add<T: S>(first: &T, second: &T) -> f32 {
first.val() + second.val()
}
This fails to compile with the error:
15 | | fn add(&self, other: &Self) -> f32 {
16 | | add(&self, other)
| | ^^^^^ expected `&Self`, found type parameter `Self`
17 | | }
I do not understand the error message, for other is of type &Self
not Self
, so why does compiler thinks otherwise?
If I change it to reference add(&self, &other)
(which doesn't seem right, since other
is already a reference type), I get another error:
|
16 | add(&self, &other)
| ^^^ the trait `S` is not implemented for `&Self`
...
26 | fn add<T: S>(first: &T, second: &T) -> f32 {
| - required by this bound in `add`
Is there a way to achieve this with default trait implementation, or this can work only with concrete types (like in this question: How do I implement the Add trait for a reference to a struct?)?
EDIT: If I call it like add(self, other)
, it tries to send the trait object, but I want to send the objects by reference. And really, I want to send concrete implementations and not trait objects.
error[E0277]: the size for values of type `Self` cannot be known at compilation time
--> src/main.rs:16:9
|
16 | add(self, other)
| ^^^ doesn't have a size known at compile-time