如何在传递迭代的向量时调用迭代器的函数?

时间:2017-10-25 10:16:10

标签: vector iterator rust

我试图迭代结构向量并从迭代器调用函数,同时将向量传递给它。

我收到此错误:

error[E0502]: cannot borrow `self.members` as immutable because it is also borrowed as mutable
  --> main.rs:40:29
   |
39 |             for member in self.members.iter_mut() {
   |                           ------------ mutable borrow occurs here
40 |                 member.func(self.members.to_vec());
   |                             ^^^^^^^^^^^^ immutable borrow occurs here
41 |             }
   |             - mutable borrow ends here

error[E0502]: cannot borrow `self.members` as immutable because it is also borrowed as mutable
  --> main.rs:40:29
   |
39 |             for member in self.members.iter_mut() {
   |                           ------------ mutable borrow occurs here
40 |                 member.func(self.members.to_vec());
   |                             ^^^^^^^^^^^^ immutable borrow occurs here
41 |             }
   |             - mutable borrow ends here

我明白这个问题是什么,但我真的不知道解决它的语法。 我尝试过各种不同的东西,如克隆和复制,但似乎无法让它正常运作。

struct Member {
    data: i32,
}

impl Copy for Member {}
impl Clone for Member {
    fn clone(&self) -> Member {
        *self
    }
}

impl Member {
    pub fn new(data: i32) -> Member {
        Member { data: data }
    }
    pub fn func(&mut self, members: Vec<Member>) {
        let mut exists = false;
        for member in members.iter() {
            if member.data == self.data + 1 {
                exists = true;
            }
        }
        if !exists {
            self.data += 1;
        }
    }
}

struct List {
    members: Vec<Member>,
}

impl List {
    pub fn new() -> List {
        let mut members = Vec::new();
        members.push(Member::new(0));
        members.push(Member::new(1));
        members.push(Member::new(3));
        List { members: members }
    }

    pub fn call_all(&mut self) {
        // Here is the issue
        for member in self.members.iter_mut() {
            member.func(self.members.to_vec());
        }
    }
}

fn main() {
    let mut list = List::new();
    list.call_all();
}

这似乎是一个简单的修复。 如果这看起来过于通用,请查看此repo of the full code

1 个答案:

答案 0 :(得分:0)

了解借款限制非常重要。只有借用的是#34; alive&#34;你无法使用任何其他手段访问该东西。 Rust不允许您以不同的方式访问相同的东西,而其中一种方式允许变异。这就是我们如何获得所有这些良好的安全保障。

在您的代码中,您使用self.members作为循环结构的一部分,可变地借用iter_mut。这就是编译器不允许您在循环内再次访问self.members的原因。

我不知道您的代码的用途是什么,但这似乎计算了您想要计算的内容:

fn main() {
    let mut v = vec![0, 1, 3];
    for i in 0..v.len() {
        if !v.contains(&(v[i] + 1)) {
            v[i] += 1;
        }
    }
    println!("{:?}", &v[..]);
}

这里,矢量不作为循环结构的一部分借用。我们迭代索引。 if表达式中的条件涉及两个临时不可变借用,这很好。在if表达式v中,可暂时借用i来改变declare i32 @printf(i8* nocapture readonly, ...) local_unnamed_addr #2 - 元素的值,而没有其他借用。没关系。