What does &* combined together do in Rust?

In short: the * triggers an explicit deref, which can be overloaded via ops::Deref.


More Detail

Look at this code:

let s = "hi".to_string();  // : String
let a = &s;

What’s the type of a? It’s simply &String! This shouldn’t be very surprising, since we take the reference of a String. Ok, but what about this?

let s = "hi".to_string();  // : String
let b = &*s;   // equivalent to `&(*s)`

What’s the type of b? It’s &str! Wow, what happened?

Note that *s is executed first. As most operators, the dereference operator * is also overloadable and the usage of the operator can be considered syntax sugar for *std::ops::Deref::deref(&s) (note that we recursively dereferencing here!). String does overload this operator:

impl Deref for String {
    type Target = str;
    fn deref(&self) -> &str { ... }
}

So, *s is actually *std::ops::Deref::deref(&s), in which the deref() function has the return type &str which is then dereferenced again. Thus, *s has the type str (note the lack of &).

Since str is unsized and not very handy on its own, we’d like to have a reference to it instead, namely &str. We can do this by adding a & in front of the expression! Tada, now we reached the type &str!


&*s is rather the manual and explicit form. Often, the Deref-overload is used via automatic deref coercion. When the target type is fixed, the compiler will deref for you:

fn takes_string_slice(_: &str) {}

let s = "hi".to_string();  // : String
takes_string_slice(&s); // this works!

Leave a Comment

Hata!: SQLSTATE[HY000] [1045] Access denied for user 'divattrend_liink'@'localhost' (using password: YES)