【问题标题】:Rust Deref vs Implementing Iterators over inner typesRust Deref vs 在内部类型上实现迭代器
【发布时间】:2021-08-02 09:18:40
【问题描述】:

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

struct SizedVec {
    items: Vec<u32>,
    cap: usize,
}

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

但是,我不确定应该实现哪些特征:IteratorIntoIterator 是否足够? the docs有很多特质 而且它们看起来有点复杂和乏味。

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

果然,这样做之后:

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
    }
}

我可以使用所有我想要的迭代器。但是我想实现一个自定义的推送逻辑,但是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);
        }
    }
}

这似乎有效,

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)
}

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

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

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

【问题讨论】:

    标签: rust iterator


    【解决方案1】:

    Deref 很好,因为您的结构特别是一个带有额外不变量的 vec(因此使其可用 as 一个 vec 似乎是明智的)但DerefMut 似乎是一个相当糟糕的主意,因为它会让调用者泄露了内部Vec(作为可变引用)并破坏了你的不变量。

    一个选项可能是Deref 到一个切片(而不是 vec),在这种情况下,DerefMut 也会给你一个切片,它有非常严格的限制,因此无法破坏你的不变量.这意味着您可能需要重新实现固有的 Vec 方法,但不能冒充Vec

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

    现在我不明白你的意思

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

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

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2023-03-31
      • 1970-01-01
      • 2022-01-08
      • 2016-03-30
      • 1970-01-01
      • 2012-02-18
      相关资源
      最近更新 更多