Rust Deref 与在内部类型上实现迭代器

Vik*_*h B 0 iterator rust

这是一个包含向量的玩具结构

struct SizedVec {
    items: Vec<u32>,
    cap: usize,
}
Run Code Online (Sandbox Code Playgroud)

我想拥有迭代函数,SizedVec这样它们就可以像我直接迭代项目一样工作。

但是,我不知道我应该实现哪些性状:是IteratorIntoIterator就够了吗?文档中有很多特征 ,它们看起来有点复杂和乏味。

然后我看到我可以使用 deref coercion 免费实现DerefDerefMut获取所有这些功能:

果然,做完之后:

impl Deref for SizedVec {
    type Target = Vec<u32>;

    fn deref(&self) -> &Self::Target {
        &self.items
    }
}

impl DerefMut for SizedVec {
    fn deref_mut(&mut self) -> &mut Self::Target {
        &mut self.items
    }
}
Run Code Online (Sandbox Code Playgroud)

我可以使用我想要的所有迭代器。但是我想实现一个自定义的推送逻辑,但是DeRef已经给了我一个推送。但是根据文档我应该没问题,因为显然查找是按顺序为每种类型完成的

impl SizedVec {
    fn from_size(size: usize) -> Self {
        Self {
            items: vec![],
            cap: size,
        }
    }

    fn push(&mut self, item: u32) {
        if self.items.len() < self.cap {
            self.items.push(item);
        }else {
            self.items.pop();
            self.items.push(item);
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

这似乎有效,

fn main () {
    let mut svec = SizedVec::from_size(2); // Custom function I implemented
    svec.push(2);
    svec.push(3);
    svec.push(4);
    svec.iter_mut().for_each(|item| {*item = *item + 2});
    println!("{}", svec); // Items: [4, 6], Cap: 2 (Implemented Display so this works)
}
Run Code Online (Sandbox Code Playgroud)

这一切似乎都很有效,但我的问题是:这是个好主意吗?如果我将我的转换SizedVec为泛型类型,我会遇到问题吗?

如果这是一个坏主意,是否有一种简单的方法可以将内部向量项的所有迭代/映射功能放到封闭结构上?

另外,是否有任何性能方面的考虑?

Mas*_*inn 5

Deref是罚款,因为你的结构是专门用另外的不变量(如此使得它可用A VECA VEC似乎是合理的),但DerefMut似乎是一个相当糟糕的主意,因为这将让来电者泄露内部Vec(如一个可变的参考),打破你的不变量。

一种选择可能是Deref切片(而不是 vec),在这种情况下,DerefMut也会为您提供一个切片,该切片具有非常严格的限制,因此将无法打破您的不变量。这意味着您可能需要重新实现固有的Vec方法,并且无法将其作为Vec.

另一种选择是根本不实现DerefMut,并为这些提供更明确的方法。还有 WRT 可迭代对象,请注意,您只需要实现IntoIterator和其他迭代器生成方法 ( .iter(), .iter_mut()):结果可以是底层集合返回的任何迭代器。

现在我不知道你的意思

但是,我不确定我应该实现哪些特征:Iterator [...] 足够了吗?

在任何情况下,您都不应该Iterator直接在您的SizedVec. 这是一个可怕的、可怕的想法。

迭代器子特征基本上是标记,它们提供额外的功能Iterator(但不一定由每种Iterator类型实现)。如果您正确委派您的迭代,则底层迭代器类型可能已经实现了那些可能的。