The multiple '&'s in Rust confuse me

fn main() {

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>
        't: 'q,

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).


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> {
    instead. Note that I’ve also elided lifetimes that don’t need their relations to output lifetimes further specified.

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.