Почему признак Index позволяет возвращать ссылку на временное значение? - PullRequest
0 голосов
/ 28 октября 2019

Рассмотрим этот простой код :

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]
    }
}

Он компилируется без проблем, но я не могу понять, почему средство проверки заимствований не жалуется на возврат ссылки на временное значение в index функция.

Почему это работает?

1 Ответ

0 голосов
/ 01 ноября 2019

Ваш пример выглядит нормально.

Черта Index способна только «просматривать» уже находящийся в объекте объект и не может использоваться для возврата произвольных динамически генерируемых данных.

В Rust невозможно вернуть ссылку на значение, созданное внутри функции, если это значение не хранится где-то постоянно (ссылки не существуют сами по себе, они всегда заимствуют некоторое значение, принадлежащее где-то).

Ссылка не может быть заимствована из переменной внутри функции, потому что все переменные будут уничтожены до возврата из функции. Время жизни описывает только то, что делает программа, и не может «заставить» что-то жить дольше, чем оно уже делает.

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 
}

Вы можете обнаружить, что возвращение &1 работает. Это потому, что 1 хранится в исполняемом файле вашей программы, который, с точки зрения программы, является постоянным хранилищем. Но 'static является исключением для литералов и утечек памяти, поэтому в большинстве случаев на это нельзя полагаться.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...