我有一个像这样的循环缓冲区:
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<T>
,而CircularBufferIterator
取决于'a
。
我看不到的部分是为什么我需要将T
生命周期添加到T: Copy
。没有一生,不能是T
吗?换句话说,当CircularBuffer
引用超过CircularBuffer
时,我看不到这种情况。 CircularBufferIterator
的参考资料比CircularBuffer
更长。
function ToBinaryTree ( arr )
{
// creates a binary tree from an array arr of comparable objects
this.Tree = { left: undefined, right: undefined };
this.CreateNode = function ( value )
{
return { val : undefined, left : undefined, right : undefined }
};
this.Insert = function (elem)
{
var node = this.CreateNode(elem);
if ( this.Tree.left == undefined )
// ... ??
};
// insert elements from array provided in "constructor"
arr.forEach(function(x){
this.Insert(x);
}.bind(this));
this.Contains = function (elem)
{
// ...
};
return this;
}
和上下文来自this blog post。
答案 0 :(得分:3)
为什么我需要将
'a
生命周期添加到T
您不能为T
添加生命周期;你说的是,无论选择T
,它只能包含超过'a
的引用。如果情况并非如此,那么我们可能会引用一个现在无效的引用类型。使用该无效参考将导致记忆不安全; Rust希望避免的一件重要事情。
我原本以为你问的是如何删除Copy
界限,所以这就是我输入的所有内容。
一个更改是从Copy
中移除CircularBuffer
绑定,但将其留在方法的实现上。然后你根本不需要在迭代器上使用它:
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
而不是&T
,因此您最终需要一个Copy
或{{ 1}}。您会注意到标准库并不需要这样做,因为它返回对集合中项目的引用。如果您确实需要非参考,那就是Clone
或Iterator::cloned
的用途。