我的目标是用一个many_iter_mut()方法生成一个NewType(Arc<RwLock<Vec<T>>>),该方法返回一个迭代器,该迭代器在内部Vec<T>上持有写锁(RwLockWriteGuard).

因此,写锁将由ManyIterMut迭代器保持,直到迭代器被删除.这不同于每次调用ManyIterMut::next()时都获得写锁定.(我已经在其他地方工作过了)

这对于使调用者能够同时设置多个元素和读取多个元素非常有用,但是是原子性的. 这样读者就可以看到从一批写入到下一批写入的一致视图. (我之前的ManyIterMut impl没有通过并发测试.

问题是,由于生命周期的问题,我无法编译ManyIterMut::next()方法.编译器似乎不喜欢write_lockManyIterMut拥有,而不是被迭代的LockedVec拥有.

给你playground块.

生成错误的代码为:

impl<'a, V, T: 'a> LendingIterator for ManyIterMut<'a, V, T>
where
    V: StorageVecWrites<T> + ?Sized,
    V::LockedData: StorageVecReads<T>,
    T: Copy,
{
    type Item<'b> = StorageSetter<'b, V, T>
    where
        Self: 'b;

    // This is the fn that won't compile.
    //
    // we can't change the fn signature, it is defined by lending_iterator::LendingIterator trait.
    fn next(&mut self) -> Option<Self::Item<'_>> {
        if let Some(i) = Iterator::next(&mut self.indices) {
            let value = self.write_lock.get_at(i).unwrap();
            Some(StorageSetter {
                phantom: Default::default(),
                write_lock: &mut self.write_lock,  // <--- this seems to be the problem.  Because it has &mut self lifetime, not Self::Item<'_> lifetime
                index: i,
                value,
            })
        } else {
            None
        }
    }
}

错误是:

error: lifetime may not live long enough
   --> src/main.rs:164:13
    |
148 |   impl<'a, V, T: 'a> LendingIterator for ManyIterMut<'a, V, T>
    |        -- lifetime `'a` defined here
...
161 |       fn next(&mut self) -> Option<Self::Item<'_>> {
    |               - let's call the lifetime of this reference `'1`
...
164 | /             Some(StorageSetter {
165 | |                 phantom: Default::default(),
166 | |                 write_lock: &mut self.write_lock,  // <--- this seems to be the problem.  Because it has &mut self lifetime, not Self::It...
167 | |                 index: i,
168 | |                 value,
169 | |             })
    | |______________^ method was supposed to return data with lifetime `'a` but it is returning data with lifetime `'1`
    |
    = note: requirement occurs because of the type `StorageSetter<'_, V, T>`, which makes the generic argument `'_` invariant
    = note: the struct `StorageSetter<'c, V, T>` is invariant over the parameter `'c`
    = help: see <https://doc.rust-lang.org/nomicon/subtyping.html> for more information about variance

error: could not compile `playground` (bin "playground") due to previous error

我错过了什么? 似乎应该可以. 还是有更简单的方法

推荐答案

write_lock: &'c mut RwLockWriteGuard<'c, V::LockedData>,

这种模式(&'a mut T<'a>)总是(几乎?)错误的.AT允许一次使用数据at most.有关更多信息,请参见Borrowing something forever .

解决办法是引入另一种生活方式.这需要一些修正,主要是在type Item<'b> = StorageSetter<'b, V, T>中将其更改为type Item<'b> = StorageSetter<'a, 'b, V, T>.

Rust相关问答推荐

交叉术语未正确清除屏幕

为什么std repeat trait绑定在impl块和关联函数之间?

如果成员都实现特征,是否在多态集合上实现部分重叠的特征?

"value is never read警告似乎不正确.我应该忽略它吗?

将数组转换为HashMap的更简单方法

为昂贵的for循环制作筛子

如何向下转换到MyStruct并访问Arc Mutex MyStruct实现的方法?

Rust编译器似乎被结果类型与anyhow混淆

习语选项<;T>;到选项<;U>;当T->;U用From定义

为什么我需要 to_string 函数的参考?

可选包装枚举的反序列化

为什么我可以使用 &mut (**ref) 创建两个实时 &mut 到同一个变量?

更新 rust ndarray 中矩阵的一行

为什么 for_each 在释放模式(cargo run -r)下比 for 循环快得多?

在构建器模式中捕获 &str 时如何使用生命周期?

在运行时在 Rust 中加载字体

如何获得对数组子集的工作可变引用?

没有通用参数的通用返回

在传输不可复制的值时实现就地枚举修改

返回 &str 但不是 String 时,borrow 时间比预期长