The multiple '&'s in Rust confuse me

fn main() {
	foot(&&"a");
}

fn foot(value: &&str) {
    println!("{:?}", value);
}

&&"a" What does it mean?

What confuses me even more:

fn foobar<'t, 'q>(set: &'q HashSet<&'t str>, key: &'q str) -> Option<&'q &'t str>
    where
        't: 'q,
{
    set.get(key)
}

What does &'q &'t str in Option<&'q &'q str> mean?

This is how I understand it. Among them, set.get returns a &T, where T represents &'t str, and the life cycle of &T is q. Is this understanding correct?

Yes, &&Foo really only means & &Foo, i.e. &T where T is &Foo.


Since &expr means: take a reference to the value of expr, consequently &&expr means: take a referene to the value of &expr.

Since "a", a string literal, is already a reference, the expression &&"a" is actually of type &&&str. The code compiles nonetheless because &&&str can be coerced to &&str (it automatically dereferences one level of indirection).

3 Likes

This function is a bit weird in that:

  • the bound 't: 'q does not need to be specified explicitly. You can leave it out, it will still be there implicitly due to the usage of the type &'q HashSet<&'t str>.
  • there’s an unnecessary relationsship between set and key that they both use the lifetime 'q. While it doesn’t really hurt in this case, it’s often a good idea to avoid unnecessarily restricting lifetimes to be the same when they don’t need to be.
  • returning &'q &'t str is a bit weird. All you can do with a &'q &'t str is dereference it to get the &'t str, then work with that. It’s just a weird as returning &u32 would be. I mean, I guess you can spare the dereferencing if you don’t need to (but then there’s little point in calling foobar at all). I’d change the function to
    fn foobar<'t>(set: &HashSet<&'t str>, key: &str) -> Option<&'t str> {
        set.get(key).copied()
    }
    
    instead. Note that I’ve also elided lifetimes that don’t need their relations to output lifetimes further specified.
5 Likes

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.