@historydev

Почему время жизни параметров берутся из дженериков?

Изучаю время жизни, дан такой пример, он конечно не скомпилируется, но суть не в этом:
fn longest<'a, 'b>(x: &'a str, y: &'b str) -> &str {


Если брать функцию с дженериком example, то тип возвращаемого значения можно представить как:

let e: u32 = example();
// или
let e = example::<u32>();


Здесь понятно, что тип дженерика дальше можно передать в параметры и куда угодно по нужде:
fn example<T>(a: &T) -> &T;

То есть тип переменной неявно попадает в дженерик или мы передаем его через ::.

Но почему тот-же синтаксис используется для времён жизни?

Откуда они берутся?

По логике выше в 'a и 'b попадает время жизни переменной которая вызывает функцию, пока очень непонятно.

Или время жизни берётся из области видимости и снова непонятно, каким образом?

Почему-то в книге мало информации на этот счёт, как минимум в текущей главе, как и в главе про обобщённые типы не было указано что тип передаётся указанными выше способами.
  • Вопрос задан
  • 105 просмотров
Решения вопроса 1
bingo347
@bingo347
Crazy on performance...
Советую почитать вот эту статью: https://habr.com/ru/articles/515034/

А вообще, времена жизни - это часть типа.
Условный u32 имеет время жизни 'static
А ссылка на u32 - &'a u32 (где 'a это диапазон от объявления исходного u32 до его последнего использования) будет иметь время жизни 'a
Пример по сложнее, ссылка на ссылку - &'a &'b u32 - будет иметь время жизни наименьшее из 'a и 'b

Передаётся через дженерик, так как функция должна работать с абстрактным временем жизни
fn example<'a>(r: &'a u32) -> &'a u32 { r }

fn f_a() {
    let a = 1;
    let r = example(&a);
}

fn f_b() {
    let b = 1;
    let r = example(&b);
}
В этом примере очевидно что переменная a в f_a будет иметь время жизни отличное от b в f_b, но example спокойно работает и с тем и с другим, то есть она является обобщённой по времени жизни, в первом случае она вернёт ссылку с временем жизни как у переменной a, во втором - как у b.

А ещё помимо времен жизни и типов в дженериках могут быть некоторые константы:
fn make_array<const SIZE: usize>(el: u32) -> [u32; SIZE] {
    [el; SIZE]
}

let arr = make_array::<3>(1); // [1, 1, 1]
Ответ написан
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы