iterator - 如何在 Rust 中的锁定结构成员上返回迭代器?

标签 iterator rust mutex

这是我所能得到的,使用 rental , 部分基于 How can I store a Chars iterator in the same struct as the String it is iterating on? .这里的区别在于 get_iter锁定成员的方法必须采用可变的自引用。

我不局限于使用租赁:我对使用 reffers 的解决方案同样满意或 owning_ref .

PhantomData在这里只是为了 MyIterMyIterable 具有正常的生命周期关系,被迭代的东西。

我也试过改变 #[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);
}

最佳答案

作为用户rodrigo在评论中指出,解决方案只是将 #[rental] 更改为 #[rental_mut]

关于iterator - 如何在 Rust 中的锁定结构成员上返回迭代器?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51664098/

相关文章:

linux - 为什么在 Linux 中 spin_lock 和 spin_unlock 之间的中断被禁用?

python - 如何控制python中迭代器结果的顺序

c++ - 如何定义类似于Vector的Vector的Double Brackets/Double Iterator运算符?

c++ - std::transform 的 lambda(parameter) 中的 const 限定符与 std::sregex_token_iterator

当代码不是时,Rust 编译器提示在循环中使用移动值

python - 无法加载基于 CI 构建的 Dylib

linux - 内核如何处理新文件的创建

java - 使用迭代器和 ArrayList 的具有 10 个记录的多个 ArrayList

rust - 一个方法的多个返回类型

multithreading - 可重用屏障算法