【问题标题】:How can I return an iterator over a locked struct member in Rust?如何在 Rust 中通过锁定的结构成员返回迭代器?
【发布时间】:2019-01-10 20:15:08
【问题描述】:

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

我不喜欢使用租赁:我对使用 reffersowning_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);
}

【问题讨论】:

  • 如果唯一的问题是mut,只需使用#[rental_mut] 而不是#[rental] 就可以解决问题,不是吗?
  • oboy,我怎么没发现?非常感谢!
  • 如果这是解决方案,您应该写一个答案并接受它,而不是将其编辑到问题中。回答您自己的问题是很正常的,并且可以让未来的读者更容易知道问题已解决。
  • @trentol,完成。看来我必须等待 24 小时才能被允许接受它:)。

标签: iterator rust mutex


【解决方案1】:

正如用户rodrigo 在评论中指出的那样,解决方案是将#[rental] 更改为#[rental_mut]

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-09-02
    • 2021-11-24
    • 1970-01-01
    相关资源
    最近更新 更多