在Rust中对一个集合进行双循环,其中一个循环会更改它

2ul0zpep  于 2023-08-05  发布在  其他
关注(0)|答案(1)|浏览(78)

我尝试迭代集合antsVec<Ant>)。我不能克隆这些对象。

for ant1 in &mut self.ants {
  for ant2 in &self.ants {
    if ant1 != ant2 && distance(ant1, ant2) <= Ant::visibility_range() {
      ant1.meet(ant2); // fn meet(&mut self, other: &Self); // - needs.
    }
  }
}

字符串
借货检查员打我的手。如何正确地做到这一点?
一个解决方案是复制所需的字段吗?

mfuanj7w

mfuanj7w1#

您可以使用split_at_mut只查看后面的蚂蚁。

for outer in 1..self.ants.len() {
    let (begin, end) = self.ants.split_at_mut(outer);
    let ant1 = begin.last_mut().unwrap();
    for ant2 in end {
        if ant1 != ant2 && distance(ant1, ant2) <= Ant::visibility_range() {
            ant1.meet(ant2);
            ant2.meet(ant1);
        }
    }
}

字符串
在这种实现中,蚂蚁无法与自身相遇,但由于meet的签名,这无论如何都是不可能的。这一点只有在蚂蚁可以不等于自身的情况下才是重要的,因此,如果您有一个合理的PartialEq实现,这并不重要。
此实现还更改了相遇的顺序。ant1将在同一点与ant2相交,但ant2ant1相交得时间早于代码中得时间.不过,它的优点是计算distance的次数是原来的一半。
如果要保持顺序,可以循环遍历前面的蚂蚁和后面的蚂蚁。

for outer in 1..self.ants.len() {
    let (begin, end) = self.ants.split_at_mut(outer);
    let (ant1, begin) = begin.split_last_mut().unwrap();
    for ant2 in begin.into_iter().chain(end) {
        if ant1 != ant2 && distance(ant1, ant2) <= Ant::visibility_range() {
            ant1.meet(ant2);
        }
    }
}


同样,这并没有将蚂蚁与其自身进行比较,但其他所有内容都与您的代码相同。

相关问题