Mam strukturę, która wygląda nieco jak poniżej:Jak przywrócić odwołanie do wartości podrzędnej wartości pod muteksem?
pub struct MyStruct {
data: Arc<Mutex<HashMap<i32, Vec<i32>>>>,
}
mogę łatwo dostać blokadę na mutex i kwerendy bazowego HashMap
:
let d = s.data.lock().unwrap();
let v = d.get(&1).unwrap();
println!("{:?}", v);
Teraz chcę uczynić metodę incapsulate Zapytanie, więc piszę coś takiego:
impl MyStruct {
pub fn get_data_for(&self, i: &i32) -> &Vec<i32> {
let d = self.data.lock().unwrap();
d.get(i).unwrap()
}
}
To oczywiście nie kompiluje, ponieważ próbuję r eturn odniesienie do danych pod mutex:
error: `d` does not live long enough
--> <anon>:30:9
|
30 | d.get(i).unwrap()
| ^
|
note: reference must be valid for the anonymous lifetime #1 defined on the block at 28:53...
--> <anon>:28:54
|
28 | pub fn get_data_for(&self, i: &i32) -> &Vec<i32> {
| ^
note: ...but borrowed value is only valid for the block suffix following statement 0 at 29:42
--> <anon>:29:43
|
29 | let d = self.data.lock().unwrap();
| ^
mogę to naprawić poprzez owinięcie HashMap
wartości do Arc
, ale wygląda brzydki (Arc
w Arc
) i komplikuje kod:
pub struct MyStruct {
data: Arc<Mutex<HashMap<i32, Arc<Vec<i32>>>>>,
}
Jaki jest najlepszy sposób podejścia do tego? Czy jest możliwe stworzenie metody, która robi to, co chcę, bez modyfikowania struktury danych?
Ładne pytanie. Spodziewałem się metody 'map()' na 'MutexGuard', jak [' Ref :: map() '] (https://doc.rust-lang.org/std/cell/struct.Ref.html#method .map) ... Dlaczego go nie ma? \ * \ _ \ * –
'' ' impl MyStruct { fn with_data (f: F) {...}} ? ' '' Czy to praca w zasadzie tylko pozwolić użytkownikowi zapewnić funkcję, która zmodyfikuje te dane, gdy są zablokowane, zamiast próbować je zwrócić? –
@ dpc.pw Tak. Myślałem również o podejściu do zamknięcia ... Nie bardzo piękne, ale robi to, czego potrzebuję ... Najlepsze rozwiązanie byłoby coś w rodzaju 'map()' jak wspomniał Lukas, lub jakiejś dziwacznej magii manipulowania życiem, ale nie mogę wymyślić żadnej ... –