0

I can't really understand the dereference here. The type of foo is TattleTell<&str>. The method len() is from foo.value, i.e. foo.value.len(). So why deref of TattleTell is invoked?

use std::ops::Deref;
struct TattleTell<T> {
    value: T,
}
impl<T> Deref for TattleTell<T> {
    type Target = T;
    fn deref(&self) -> &T {
        println!("{} was used!", std::any::type_name::<T>());
        &self.value
    }
}
fn main() {
    let foo = TattleTell {
        value: "secret message",
    };
    // dereference occurs here immediately
    // after foo is auto-referenced for the
    // function `len`
    println!("{}", foo.len());
}
Chayim Friedman
  • 47,971
  • 5
  • 48
  • 77
  • 1
    `foo.value.len()` would access `.len()` without invoking `.deref()`, but since there's no `.len()` method on `foo` Rust tries inserting `.deref()`. – eggyal May 05 '22 at 11:15
  • @eggyal Oops, I've mixed it up with Go's anonymous field, under the assumption that `foo` gets the methods of `foo.value`. XD – EricNotSame May 05 '22 at 13:23

1 Answers1

0

I won't fully describe Rust's auto-dereferencing rules because they are covered in other answers. For example, here.

In your case, you are trying to call a method, len, on a TattleTell<&'static str>. This type doesn't directly have that method so, using the rules in that other answer, Rust goes looking for it, using the following steps:

  1. Check if the method exists on &TattleTell<&'static str>. It doesn't.
  2. Check if the method exists on *&TattleTell<&'static str>. Due to your Deref implementation, this is a &'static str, so the method exists.
Peter Hall
  • 53,120
  • 14
  • 139
  • 204
  • I'm new to Rust and not familiar with the jargons, so I don't know the exact keyword to search. Thanks for your time. :-) – EricNotSame May 05 '22 at 13:42