这是我所能达到的程度,使用rental,部分基于如何在与其迭代的字符串相同的结构体中存储Chars迭代器?。这里的区别在于锁定成员的
我不一定要使用rental:如果使用reffers或owning_ref解决方案,我会很高兴。
我也尝试将
get_iter
方法必须使用可变自身引用。我不一定要使用rental:如果使用reffers或owning_ref解决方案,我会很高兴。
PhantomData
在这里存在只是为了让MyIter
与被迭代的东西MyIterable
之间保持正常的生命周期关系。我也尝试将
#[rental]
更改为#[rental(deref_mut_suffix)]
,并将MyIterable.get_iter
的返回类型更改为Box<Iterator<Item=i32> + 'a>
,但这给我带来了其他生命周期错误,这些错误源自于我无法解释的宏。#[macro_use]
extern crate rental;
use std::marker::PhantomData;
pub struct MyIterable {}
impl MyIterable {
// In the real use-case I can't remove the 'mut'.
pub fn get_iter<'a>(&'a mut self) -> MyIter<'a> {
MyIter {
marker: PhantomData,
}
}
}
pub struct MyIter<'a> {
marker: PhantomData<&'a MyIterable>,
}
impl<'a> Iterator for MyIter<'a> {
type Item = i32;
fn next(&mut self) -> Option<i32> {
Some(42)
}
}
use std::sync::Mutex;
rental! {
mod locking_iter {
pub use super::{MyIterable, MyIter};
use std::sync::MutexGuard;
#[rental]
pub struct LockingIter<'a> {
guard: MutexGuard<'a, MyIterable>,
iter: MyIter<'guard>,
}
}
}
use locking_iter::LockingIter;
impl<'a> Iterator for LockingIter<'a> {
type Item = i32;
#[inline]
fn next(&mut self) -> Option<Self::Item> {
self.rent_mut(|iter| iter.next())
}
}
struct Access {
shared: Mutex<MyIterable>,
}
impl Access {
pub fn get_iter<'a>(&'a self) -> Box<Iterator<Item = i32> + 'a> {
Box::new(LockingIter::new(self.shared.lock().unwrap(), |mi| {
mi.get_iter()
}))
}
}
fn main() {
let access = Access {
shared: Mutex::new(MyIterable {}),
};
let iter = access.get_iter();
let contents: Vec<i32> = iter.take(2).collect();
println!("contents: {:?}", contents);
}
mut
,那么只需要使用#[rental_mut]
而不是#[rental]
应该就可以解决了,不是吗? - rodrigo