The goal: implement a default implementation of a trait for any type which has a to_string()
.
So my approach might actually be completely wrong. But I am asking the question this way first because it's an interesting one nonetheless.
use core::fmt::Display
trait MyStyle<T: Display> {
fn pretty(&self) -> String {
let buf = self.to_string();
// manipulate buf
buf
}
}
In the above code, what exactly is self
? My env (through rust-analyzer
) just tells me self: &Self // size = 8, align = 0x8
. But what type is it?
Obivously this code doesn't work, or I wouldn't be here, because I get
the method
to_string
exists for reference&Self
, but its trait bounds are not satisfied.
If it says to_string
exists, that suggests that self
could be some reference to Display
, but I don't understand the rest, and why it does not compile.
Self
in a trait refers to the type implementing that trait. Thus, in the trait definition it represents any type that implements that trait. You could think of it as a generic S
where S: MyTrait<T>
. It does not refer to one singular type.
The goal: implement a default implementation of a trait for any type which has a to_string().
This is pretty simple and you may have over complicated things by making your trait generic. This is likely what you want:
use std::fmt::Display;
trait MyStyle: Display {
fn pretty(&self) -> String {
let buf = self.to_string();
// manipulate buf
buf
}
}
Likely with an additional impl<T> MyStyle for T where T: Display {}
to actually create a blanket implementation for anything that implements Display
.