Когда мне нужно указывать явные времена жизни в Rust?

Если у меня есть две функции

// implicit
fn foo(x: &i32) {
}

// explicit
fn bar<'a>(x: &'a i32) {
}

Когда foo вернет ошибку и bar будет правильным заголовком функции? Я запутался в , почему я бы явным образом объявлял всю жизнь:

"a читает" время жизни a. Технически каждая ссылка имеет некоторые связанный с ним, но компилятор позволяет вам общие случаи.

Я понимаю, что такое жизнь, но что явным образом задаю для меня время жизни 'a do? Для справки я использую книгу ржавчины в качестве материала для чтения

Ответ 1

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

Я предполагаю, что вам нужен простой пример, где сроки жизни являются обязательными. Представьте себе следующий сценарий:

struct Blah<'a> {
    hoy: &'a u8
}

fn want_a_hoy(blah: &Blah) -> &u8 {
    blah.hoy
}

Цель очевидна, но компилятор не справляется с ней:

<anon>:7:35: 7:38 error: missing lifetime specifier [E0106]
<anon>:7     fn want_a_hoy(blah: &Blah) -> &u8 {
                                           ^~~
<anon>:7:35: 7:38 help: see the detailed explanation for E0106
<anon>:7:35: 7:38 help: this function return type contains a borrowed value, but 
                        the signature does not say which one of `blah` 2 elided 
                        lifetimes it is borrowed from

В этом случае аннотации решают проблему:

fn want_a_hoy<'a, 'b>(blah: &'b Blah<'a>) -> &'a u8 {
    blah.hoy
}

Здесь вы указываете 'a дважды (на Blah<'a> и &'a). Это та же самая жизнь! Итак, вы говорите компилятору: "Эта функция ссылается на бла, содержащий внутреннюю ссылку. Я верну что-то, что живет точно столько же, сколько внутренняя ссылка бла". В этом случае подпись дает сильный намек на то, что вы, скорее всего, вернете что-то, исходящее от внутренних бла-бла.