Вернуть сопоставленные данные из parking_lot :: RwLock - PullRequest
1 голос
/ 28 февраля 2020

Моя структура имеет вектор внутри parking_lot::RwLock, и одна функция-член должна возвращать защищенный элемент из этого вектора:

use parking_lot::*;

struct S {
    v: RwLock<Vec<String>>,
}

impl S {
    fn f(&self, i: usize) -> MappedRwLockReadGuard<'_, Option<&String>> {
        RwLockReadGuard::map(self.v.read(), |unlocked| &unlocked.get(i))
    }
}

(это упрощенное ядро ​​проблемы, а не реальная code)

Код проходит проверку типов, но я получаю ошибки на весь срок жизни для f. Есть ли способ изменить код так, чтобы он звучал и прошел проверку заимствования?

Ошибка:

error[E0495]: cannot infer an appropriate lifetime for lifetime parameter in function call due to conflicting requirements
  --> src/lib.rs:9:66
   |
9  |         RwLockReadGuard::map(self.v.read(), |unlocked| &unlocked.get(i))
   |                                                                  ^^^
   |
note: first, the lifetime cannot outlive the anonymous lifetime #2 defined on the body at 9:45...
  --> src/lib.rs:9:45
   |
9  |         RwLockReadGuard::map(self.v.read(), |unlocked| &unlocked.get(i))
   |                                             ^^^^^^^^^^^^^^^^^^^^^^^^^^^
note: ...so that reference does not outlive borrowed content
  --> src/lib.rs:9:57
   |
9  |         RwLockReadGuard::map(self.v.read(), |unlocked| &unlocked.get(i))
   |                                                         ^^^^^^^^
note: but, the lifetime must be valid for the anonymous lifetime #1 defined on the method body at 8:5...
  --> src/lib.rs:8:5
   |
8  | /     fn f(&self, i: usize) -> MappedRwLockReadGuard<'_, Option<&String>> {
9  | |         RwLockReadGuard::map(self.v.read(), |unlocked| &unlocked.get(i))
10 | |     }
   | |_____^
note: ...so that the expression is assignable
  --> src/lib.rs:9:9
   |
9  |         RwLockReadGuard::map(self.v.read(), |unlocked| &unlocked.get(i))
   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
   = note: expected  `lock_api::rwlock::MappedRwLockReadGuard<'_, _, std::option::Option<&std::string::String>>`
              found  `lock_api::rwlock::MappedRwLockReadGuard<'_, _, std::option::Option<&std::string::String>>`

1 Ответ

0 голосов
/ 28 февраля 2020

Решение состоит в том, чтобы использовать RwLockReadGuard::try_map() и изменить тип возвращаемого значения с MappedRwLockReadGuard<'_, Option<&_>> на Option<MappedRwLockReadGuard<'a, _>>:

impl S {
    fn f(&self, i: usize) -> Option<MappedRwLockReadGuard<'_, String>> {
        RwLockReadGuard::try_map(self.v.read(), |unlocked| unlocked.get(i)).ok()
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...