如何在Rust中的锁定结构成员上返回迭代器? [英] How can I return an iterator over a locked struct member in Rust?

查看:215
本文介绍了如何在Rust中的锁定结构成员上返回迭代器?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

使用租借,部分基于怎么办?我将Chars迭代器存储在与它迭代的String相同的结构中?。这里的区别是锁定成员的 get_iter 方法必须采用可变的自引用。

Here is as far as I could get, using rental, partly based on How can I store a Chars iterator in the same struct as the String it is iterating on?. The difference here is that the get_iter method of the locked member has to take a mutable self reference.

我'与使用租赁无关:我对使用参考 owning_ref 。

I'm not tied to using rental: I'd be just as happy with a solution using reffers or owning_ref.

这里只存在PhantomData ,以便 MyIter 承担与 MyIterable 的正常生命周期关系,正在迭代的东西。

The PhantomData is present here just so that MyIter bears the normal lifetime relationship to MyIterable, the thing being iterated over.

我也尝试将#[rental] 更改为#[租赁(deref_mut_suffix)] 并将 MyIterable.get_iter 的返回类型更改为 Box< Iterator< Item = i32> +'a> 但是这给了我其他生命周期错误,这些错误源于我无法破译的宏。

I also tried changing #[rental] to #[rental(deref_mut_suffix)] and changing the return type of MyIterable.get_iter to Box<Iterator<Item=i32> + 'a> but that gave me other lifetime errors originating in the macro that I was unable to decipher.

#[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]

As user rodrigo has pointed out in a comment, the solution is simply to change #[rental] to #[rental_mut].

这篇关于如何在Rust中的锁定结构成员上返回迭代器?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆