【问题标题】:How to express lifetime for Rust iterator for a container如何表示容器的 Rust 迭代器的生命周期
【发布时间】:2016-04-18 20:54:37
【问题描述】:

我有一个这样的循环缓冲区:

struct CircularBuffer<T: Copy> {
    seqno: usize,
    data: Vec<T>,
}

我想创建一个作为迭代器的外部结构。该结构将引用CircularBuffer 的内部数据向量,如下所示:

struct CircularBufferIterator<'a, T: 'a + Copy> {
    buffer: &'a CircularBuffer<T>,
    position: usize,
    limit: usize,
}

这是我能想到的最好的实际编译。您能否建议一种更好的方式来表达CircularBufferIterator 依赖于CircularBuffer 对象?

困扰我的是T: 'a + Copy。我想知道是否有可能或者说不是T 类型,但CircularBuffer&lt;T&gt;CircularBufferIterator 依赖的类型是否有意义。

我没有看到的部分是为什么我需要将'a 生命周期添加到T。那不能是T: Copy,没有一生吗?换句话说,我看不到T 引用比CircularBuffer 寿命更长的情况。是 CircularBuffer 引用比 CircularBufferIterator 寿命更长。

CircularBuffer 和上下文来自this blog post

【问题讨论】:

  • 我不清楚所提出的解决方案有什么问题。 T 必须比 'a 寿命更长,以防止悬空指针; T 必须是 Copy,因为您已经定义了 CircularBuffer
  • 感谢您的格式化帮助。我不确定是否有问题。我只是不完全理解它是如何工作的。我没有看到的部分是为什么我需要为 T 添加一个生命周期。那不能是 T:复制,没有生命周期吗?换句话说,我看不到 T 引用超过 CircularBuffer 的情况。它是 CircularBuffer 引用比 CBIterator 寿命更长。所以我一直在寻找一种更好的方式来表达这一点。

标签: rust


【解决方案1】:

为什么我需要将'a生命周期添加到T

您并没有为T 添加生命周期;你是说无论选择什么T,它都只能包含'a更有效的引用。如果不是这种情况,那么我们可能会引用一个类型,该类型的引用现在无效。使用该无效引用会导致内存不安全; Rust 试图避免的一个关键问题。


我原本以为你在问如何删除Copy 绑定,所以这是我输入的所有内容。

一项更改是从CircularBuffer 中删除绑定的Copy,但将其保留在方法的实现上。那么你在迭代器上根本不需要它:

struct CircularBuffer<T> {
    seqno: usize,
    data: Vec<T>,
}

struct CircularBufferIterator<'a, T: 'a> {
    buffer: &'a CircularBuffer<T>,
    position: usize,
    limit: usize,
}

另一个变化是完全避免对CircularBuffer 的直接引用,并将直接迭代器保留在Vec 中:

struct CircularBufferIterator<'a, T: 'a> {
    first: std::slice::Iter<'a, T>,
    second: Option<std::slice::Iter<'a, T>>,
}

但是,查看Iterator 实现,我发现它返回T,而不是&amp;T,因此您最终需要CopyClone 的类型。您会注意到标准库不需要这样做,因为它返回对集合中项目的引用。如果您确实需要非参考,这就是 into_iterIterator::cloned 的用途。

【讨论】:

  • 这说明了很多,非常感谢!我真的很喜欢切片的想法。我会用它做实验。我相信这是最接近我想要实现的目标。
猜你喜欢
  • 2020-07-26
  • 1970-01-01
  • 1970-01-01
  • 2021-08-29
  • 1970-01-01
  • 2013-07-03
  • 2015-11-15
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多