Я тут воюю с borrow checker’ом…
Обращаю внимание - цель данного вопроса не в том, чтобы заставить это компилиться. а в том, чтобы понять, что происходит. То есть впринципе, мне понятно - неверно расставлено время жизни. Но почему такое время жизни неверно? Если убрать время жизни, то этот код откомпилится. Компилятор сам выведет времена жизни. То есть фактически, вопрос в том, как их расставляет компилятор.
use std::collections::HashMap;
trait HasName{
fn print_name(&self);
}
fn foo<'a>(map: &'a mut HashMap<i32, Box<HasName+ 'a>>, k: i32){
}
fn main() {
let mut map:HashMap<i32, Box<HasName>> = HashMap::new();
foo(&mut map, 1);
}
Мне как бы здравый смысл подсказывает, что ссылка на мапу не может жить меньше, чем живет структура. Вот в коде выше я это и указал - как у мапы, так и у структуры время жизни 'a. Но это не прокатывает. Я не пойму - почему? Ведь по определению, когда мапа умирает - то она вызывает умирание HasName. То есть (согласно моему пониманию), время жизни получается одинаковое.
Ладно… Дадим каждой сущности свое время жизни.
Сигнатура получается такой:
fn foo<'a, 'b>(map: &'a mut HashMap<i32, Box<HasName+ 'b>>, k: i32)
В этом случае, компиляция и прокатывает - но я снова не пойму почему. Ведь нигде не указано, что 'a - более долгое время жизни, чем 'b. А вдруг я в эту функцию подам объекты, у которых время жизни будет перепутано?
Это навело меня на мысль, что времена жизни перечисляются в порядке от большего к меньшему. Проверим это, поменяв местами 'a с 'b:
fn foo<'b, 'a>....
Результат - все компилится. То есть получается, чекеру не важно какое время жизни больше, а какое меньше. Но когда они равны (как в первом примере) - это получается ошибка. Очень странное поведение. Тем более, что у нас де-факто они и есть равны: 'a=='b, с точностью до порядка создания и освобождения ресурсов.