rust 重构Struct的方法:无法将'*self'借用为不可变的,因为它也被借用为可变的

y0u0uwnf  于 2022-12-19  发布在  其他
关注(0)|答案(1)|浏览(155)

我想创建一个结构,其中一个领域是在其他功能的演变。我可以做到这一点,但我认为它可以巧妙地重构。
下面是实现这一目标的最小代码:

struct Example {
    data: Vec<bool>,
    elements: Vec<usize>,
    data2: bool
}

impl Example {
    fn decide(&self, index: usize)-> usize{
        let mut counter = 0;
        for (i,&b) in self.data.iter().enumerate() {
            if b && i < index && self.data2  {
                counter += 1;
            }
        }
        counter
    }

    fn evolve(&mut self){
        for element in self.elements.iter_mut(){
            if self.decide(*element) == 4 {
                *element += 1
            }
        }
    }
}

编译器指出存在错误:'

error[E0502]: cannot borrow `*self` as immutable because it is also borrowed as mutable
  --> src/lib.rs:20:16
   |
19 |         for element in self.elements.iter_mut() {
   |                        ------------------------
   |                        |
   |                        mutable borrow occurs here
   |                        mutable borrow later used here
20 |             if self.decide(*element) == 4 {
   |                ^^^^^^^^^^^^^^^^^^^^^ immutable borrow occurs here

在这个精确的例子中,很容易将第13行替换为decide函数的整个定义中的if self.decide(*element) == 4 {,并且它可以工作:

struct Example {
    data: Vec<bool>,
    elements: Vec<usize>,
    data2: bool,
}

impl Example {
    fn evolve(&mut self) {
        for element in self.elements.iter_mut() {
            let mut counter = 0;
            for (i, &b) in self.data.iter().enumerate() {
                if b && i < *element && self.data2 {
                    counter += 1;
                }
            }
            if counter == 4 {
                *element += 1
            }
        }
    }
}

但是在我的例子中,decide函数很大,我想减小evolve的大小,有可能吗?

bmvo0sr5

bmvo0sr51#

最简单的修复方法是向decide()传递它所需的数据,而不是接收&self

fn decide(data: &[bool], data2: bool, index: usize) -> usize {
    let mut counter = 0;
    for (i, &b) in data.iter().enumerate() {
        if b && i < index && data2 {
            counter += 1;
        }
    }
    counter
}

fn evolve(&mut self) {
    for element in self.elements.iter_mut() {
        if Self::decide(&self.data, self.data2, *element) == 4 {
            *element += 1
        }
    }
}

Playground

相关问题