Можно ли вернуть статически сохраненные значения в виде ссылок из функции?

Я новичок в Rust. Я хотел бы иметь возможность создавать переменную со статическим временем жизни внутри функции и возвращать ссылку на нее. Как можно выполнить следующее в Rust:

std::vector<int>& get_ints() {
   static bool run_yet = false;
   static std::vector<int> ints;
   if ( ! run_yet ) {
       run_yet = true;
       for ( int i=0; i < 10; ++i ) {
           ints.push_back(i);
       }
   }
   return ints;
}

Я считаю, что это может иметь какое-то отношение к жизням, но я не уверен.

Вы спрашиваете о статическом объекте OnceCell?

freakish 11.04.2024 00:14

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

cdhowie 11.04.2024 02:48
Почему Python в конце концов умрет
Почему Python в конце концов умрет
Последние 20 лет были действительно хорошими для Python. Он прошел путь от "просто языка сценариев" до основного языка, используемого для написания...
2
2
135
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

OnceLock делает то, что вы ищете. Он запустит код в get_or_init, только если он не запускался ранее.

use std::sync::OnceLock;

pub fn get_ints() -> &'static [u32] {
    static CELL: OnceLock<Vec<u32>> = OnceLock::new();
    CELL.get_or_init(|| (0..10).collect()).as_slice()
}

fn main() {
    println!("{:?}", get_ints());
}

детская площадка

Возвращать Vec довольно бессмысленно, хотя если это не mut... &'static [u32] было бы более «лучшей практикой».

Finomnis 11.04.2024 01:31

абсолютно верно, отредактировано соответственно.

Marcus Dunn 11.04.2024 02:34

Лично я бы пошел дальше и сохранил его в куче в Box<[u32]>. Также мелкие гниды: ::<Vec<u32>> является излишним, поскольку это можно сделать вывод, и .as_slice() является лишним, поскольку для него будет применено автоматическое разыменование. детская площадка

eggyal 11.04.2024 03:55

Да, кроме того, ОП исключил 10, так что правильный диапазон будет 0..10.

eggyal 11.04.2024 03:57

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