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

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

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

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

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

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

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

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's return type contains a borrowed value, but 
                        the signature does not say which one of `blah`'s 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). Это та же самая жизнь! Итак, что вы говорите компилятору здесь: "Эта функция берет ссылку на бла, содержащую внутреннюю ссылку. Я верну то, что живет ровно столько же, сколько внутренняя ссылка на бла". В этом случае подпись дает сильный намек на то, что вы, скорее всего, вернете что-то из внутренних источников бла.

Другие вопросы по тегам