1

I implemented the Deref trait for the MyString struct which allows me to use an object of type MyString via *o or o.deref().

But when I implement the Drop trait for MyString then the already implemented Deref trait cannot be used inside the Drop trait. Why?

use std::ops::Deref;
use std::ops::DerefMut;

struct MyString {
    s: String,
}

impl Deref for MyString {
    type Target = String;

    fn deref(&self) -> &Self::Target {
        &self.s
    }
}

impl DerefMut for MyString {
    fn deref_mut(&mut self) -> &mut Self::Target {
        &mut self.s
    }
}

impl Drop for MyString {
    fn drop(&mut self) {
        // println!("string dropped: {}", *self); // `MyString` doesn't implement `std::fmt::Display`
        // println!("string dropped: {}", self.deref()); // `main::MyString` doesn't implement `std::fmt::Display`

        println!("string dropped: {}", self.s); // works
    }
}
let s1 = MyString {
    s: "abc".to_string(),
};
println!("s1: {}", *s1);
println!("s1: {}", s1.deref());
Chayim Friedman
  • 47,971
  • 5
  • 48
  • 77
  • 2
    You can and you are but, but you are calling it on a `&mut MyString` which will deref to `MyString`. You should try `&**self` instead (first derefing the `&mut` _then_ derefing the `MyString`) – isaactfa Jun 19 '23 at 19:29

1 Answers1

5

Because self in deref is a reference, you need to dereference twice:

println!("string dropped: {}", **self);
println!("string dropped: {}", self.deref().deref());
Chayim Friedman
  • 47,971
  • 5
  • 48
  • 77