Hallo,
i have tried to implement a struct which should mimick the behaviour of Box<T> (mostly, Box is special and cannot be implemented by hand (there is no DerefMove trait)...).
I implemented the Deref, DerefMut trait and the Display trait, but it creates a recursion if I try to dereference &self in the Display trait. I'm not sure why this happens, but it looks like the Deref trait is ignored.
Sidenote: My test struct does not allocate data on the heap in contrast to Box<T>.
My code first:
struct ABox<T> {
val: T
}
use std::{
ops::{
Deref, DerefMut
}
};
impl<T> Deref for ABox<T> {
type Target = T;
fn deref(&self) -> &Self::Target {
&self.val
}
}
impl<T> DerefMut for ABox<T> {
fn deref_mut(&mut self) -> &mut T{
&mut self.val
}
}
impl<T: std::fmt::Display> std::fmt::Display for ABox<T> where ABox<T>: Deref {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
std::fmt::Display::fmt(&(*self), f) // fail: Creates a recursion (maybe because the Deref trait is not respected by the compiler?)!
}
}
fn main() {
let a = ABox{val:123};
println!("{}", a);
}
I'm not sure why this happens. Shouldn't the Deref trait make sure, that *self is resolved to T, so that &(*self) resolves to &T not &ABox<T>? Currently it looks like the deref operator does not respect the existence of the Deref trait.
This does not compile: <ABox<T> as Deref>::Target cannot be formatted with the default formatter, the trait std::fmt::Display is not implemented for <ABox<T> as Deref>::Target
Thats weird because in this example T is a i32 and I'm sure it implements Display
What does *Self do? Does it dereferene to the real type, in this case &ABox<T>?
That's it. both &**self or <T as std::fmt::Display>::fmt works now. Why does this constraint produces this error (it makes no sense to me) and what does it mean to dereference self twice? Is *Self = &ABox<T>?