rust - 一生可能活得不够长

标签 rust reference lifetime

我定义了一个结构体,它只有一个类型为 T 的元素切片。

pub struct MyStruct<'a, T> {
    slice: &'a mut [T],
}

我想为 MyStruct 定义一个 Iterator,它会生成一个包含 10 个元素的切片的 MyStruct

impl<'a, E> Iterator for MyStruct<'a, E> {
    type Item = MyStruct<'a, E>;

    fn next(&mut self) -> Option<Self::Item> {
        if self.slice.len() < 10 {
            return None;
        } else {
            let (head, tail) = self.slice.split_at_mut(10);

            self.slice = tail;

            Some(MyStruct { slice: head })
        }
    }
}

但不幸的是我的生活有问题。

error: lifetime may not live long enough
  --> src/lib.rs:12:32
   |
5  | impl<'a, E> Iterator for MyStruct<'a, E> {
   |      -- lifetime `'a` defined here
...
8  |     fn next(&mut self) -> Option<Self::Item> {
   |             - let's call the lifetime of this reference `'1`
...
12 |             let (head, tail) = self.slice.split_at_mut(10);
   |                                ^^^^^^^^^^^^^^^^^^^^^^^^^^^ argument requires that `'1` must outlive `'a`

我不是一生中的专家,如果有人能向我指出我在这里做错了什么,我将不胜感激。

最佳答案

问题How can I create my own data structure with an iterator that returns mutable references?很好地解释了为什么不允许这样做。但不管怎么说,或者至少暗示,没有不安全的代码就不可能做到这一点(“现在你可能想知道:标准库作者是如何编写可变向量迭代器的?答案很简单:他们使用了不安全的代码."),对于纯切片来说,这实际上是可能的。

技巧很简单:不要使用限制性 self 引用中的 self.slice,而是将其替换为空切片,现在我们拥有具有完整生命周期的切片:

fn next(&mut self) -> Option<Self::Item> {
    if self.slice.len() < 10 {
        return None;
    } else {
        let slice = std::mem::take(&mut self.slice);
        let (head, tail) = slice.split_at_mut(10);
        self.slice = tail;
        Some(MyStruct { slice: head })
    }
}

关于rust - 一生可能活得不够长,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/74798363/

相关文章:

c++ - 通过引用 vector 传递的线程函数启动缓慢

rust - 为什么这个值活得不够长?

rust - 对and_then中的 rust future 采取封闭论证的所有权

rust - 为什么我会收到错误 "the trait ` Foo` is not implemented for `&mut T` “即使 T 实现了特征?

memory - 在 Lua 中通过引用删除变量

c++ - 异步函数调用的参数生命周期

C++基础指针问题

rust - 尝试在 rust api上实现rocket_cors CorsOptions

rust - 如何从闭包中取回移动值的所有权?

c++ - 将 "this"转换为引用指针