Время жизни элемента глобальной хэш-карты с помощью lazy_static в Rust

#rust #static #lifetime #lazy-static

Вопрос:

Я новичок в Ржавчине.

Я определяю глобальную User хэш-карту by lazy_static .

Есть целая жизнь User , поэтому я должен установить ее на всю жизнь lazy_static . Кажется, что 'static можно использовать только в lazy_static .

Вот вопрос: могу ли я теперь вставить «нестатического» пользователя в хэш-карту?

Вот код, который вставляет нестатического пользователя:

 use std::collections::HashMap;
use lazy_static::lazy_static;
use std::sync::Mutex;

struct User<'a> {
    name: amp;'a str,
    score: f32,
}

lazy_static! {
    static ref USERS: Mutex<HashMap<u64, User<'static>>> = Mutex::new(HashMap::new());
}

fn new_user(id: u64, name: amp;str, score: f32) {
    let user = User { name, score };
    USERS.lock().unwrap().insert(id, user);
}
fn remove_user(id: u64) {
    USERS.lock().unwrap().remove(amp;id);
}

fn main() {
    new_user(1, "hello", 1.2);
    remove_user(1);
}
 

Вот в чем ошибка:

 error[E0621]: explicit lifetime required in the type of `name`
  --> src/main.rs:16:38
   |
16 |     USERS.lock().unwrap().insert(id, user);
   |                                      ^^^^ lifetime `'static` required

 

Комментарии:

1. Вы не можете — так lazy_static как сохраняете объект живым до конца программы, принимая любое время жизни, отличное 'static от того, которое позволило бы ссылке внутри сохраненного значения (например, name в случае User типа) стать недействительной, все еще находясь в хэш-карте. User Структура должна содержать объект, принадлежащий String вместо amp;str .

2. Спасибо. Я могу изменить имя на String , но там будет другая ссылка User , например amp;Class . Он не может вместить все.

3. Должен ли я использовать Arc<Class> для замены amp;Class ?

4. Это или просто Class , в зависимости от варианта использования.

5. Я сомневаюсь, что использование ленивой статики в вашем случае имеет смысл. xy проблема, с которой мы столкнулись здесь

Ответ №1:

Если вам нужно иметь список User s в каждом Class , и каждый User из них уникален id , просто сохраните id s в каждом экземпляре Class (и везде, где еще у вас была бы ссылка на a User ). u64 есть Clone , значит, все это работает.