简体   繁体   中英

Why does the Index trait allow returning a reference to a temporary value?

Consider this simple code :

use std::ops::Index;
use std::collections::HashMap;

enum BuildingType {
    Shop,
    House,
}

struct Street {
    buildings: HashMap<u32, BuildingType>,
}

impl Index<u32> for Street {
    type Output = BuildingType;

    fn index(&self, pos: u32) -> &Self::Output {
        &self.buildings[&pos]
    }
}

It compiles with no issues, but I cannot understand why the borrow checker is not complaining about returning a reference to temporary value in the index function.

Why is it working?

You example looks fine.

The Index trait is only able to "view" what is in the object already, and it's not usable for returning arbitrary dynamically-generated data.

It's not possible in Rust to return a reference to a value created inside a function, if that value isn't stored somewhere permanently (references don't exist on their own, they always borrow some value owned somewhere).

The reference can't be borrowed from a variable inside the function, because all variables will be destroyed before the function returns. Lifetimes only describe what the program does, and can't "make" something live longer than it already does.

fn index(&self) -> &u32 {
   let tmp = 1;
   &tmp  // not valid, because tmp isn't stored anywhere
}
fn index(&self) -> &u32 {
   // ok, because the value is stored in self,
   // which existed before this function has been called
   &self.tmp 
}

You may find that returning &1 works. That's because 1 is stored in your program's executable which, as far as the program is concerned, is permanent storage. But 'static is an exception for literals and leaked memory, so it's not something you can rely on in most cases.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM