迭代一个结构体向量

8

我有一个结构体,其中包含另一个结构体类型的向量。

struct Element {
    val: String,
}

struct Collection {
    elements: Vec<Element>,
}

impl Collection {
    fn process(&mut self) {
        for entry in &self.elements.iter_mut() {
            entry.val = "New value".to_string();
            println!("{}", entry.val);
        }
    }
}

fn main() {
    let e1 = Element {
        val: "My first entry".to_string(),
    };
    let e2 = Element {
        val: "My second entry".to_string(),
    };
    let mut c = Collection { elements: vec![] };
    c.elements.push(e1);
    c.elements.push(e2);
    c.process();
}

当我尝试迭代它时,会出现以下错误:
error[E0277]: the trait bound `&std::slice::IterMut<'_, Element>: std::iter::Iterator` is not satisfied
  --> src/main.rs:11:22
   |
11 |         for entry in &self.elements.iter_mut() {
   |                      -^^^^^^^^^^^^^^^^^^^^^^^^
   |                      |
   |                      `&std::slice::IterMut<'_, Element>` is not an iterator; maybe try calling `.iter()` or a similar method
   |                      help: consider removing 1 leading `&`-references
   |
   = help: the trait `std::iter::Iterator` is not implemented for `&std::slice::IterMut<'_, Element>`
   = note: required by `std::iter::IntoIterator::into_iter`

我认为这是因为&self.elements实际上是一个引用。使用self.elements也可以工作,但我希望修改实际的对象而不是副本。
有什么正确的方法来做到这一点吗?
1个回答

14

切换至此:

for entry in self.elements.iter_mut() { /* ... */ }

更常用的说法是:

for entry in &mut self.elements { /* ... */ }

IterMut 包含一个对向量中项目的引用(因此将直接更改向量项目),但它本身是堆栈上的对象,随着迭代的进行而发生更改。

the trait bound `&std::slice::IterMut<'_, Element>: std::iter::Iterator` is not satisfied
这意味着你通过引用得到了一个IterMut。也就是说,优先级与你想象的不同:
&self.elements.iter_mut() 
&(self.elements.iter_mut()) // Is this
(&self.elements).iter_mut() // Not this

不过,我们需要做类似这样的事情:

(&mut self.elements).iter_mut()

因为iter_mut需要一个可变引用作为接收者。Rust能够理解这一点,让我们可以直接执行简单的版本并适当传递可变性:

self.elements.iter_mut()

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接