使用结构本身的值更新结构给出:“不能借用`*self`作为可变的,因为它也被借用为不可变的”

2023-11-30

我正在尝试创建一个struct修改它的current_value通过附加一些“常量”字符串first_step这是定义时struct首先被创建。

code

fn main() {
    let mut adder = Adder {
        current_value: "init".to_string(),
        first_step: ", first".to_string(),
    };
    adder.do_something()
}

struct Adder {
    current_value: String,
    first_step: String,
}

impl Adder {
    fn add(&mut self, value: &String) {
        self.current_value = format!("{}{}", self.current_value, value);
    }

    fn do_something(&mut self) {
        // cannot borrow `*self` as mutable because it is also borrowed as immutable
        // mutable borrow occurs here rustc(E0502)
        // main.rs(24, 18): immutable borrow occurs here
        // main.rs(24, 14): immutable borrow later used by call
        self.add(&self.first_step);
    }
}

操场

我认为错误非常明显(self in self.add被借用为可变的,因为签名add has &mut self,但是要附加的值也来自self,但是这次借用的是不可变的,我们不能借用self可变和不可变)。

但我不知道如何解决这个问题,创建一个数据结构,可以使用创建结构本身时定义的一些“常量”值来更新自身。在实际的“现实生活”案例中我有一个struct其中包含两个file and file_header: String,我想要一个方法来编写file_header进入file.


Rust does允许借用parts of a struct分开,但是当你调用一个函数/方法时&mut Self,总是借用整个struct— 函数体永远不会用作附加信息。因此,解决诸如您想要使用另一部分的信息来改变结构的一部分之类的问题的解决方案是重写您的函数签名,以便它does有必要的信息。

impl Adder {
    /// Algorithm implementation; takes all components explicitly.
    /// Is not a method.
    fn add_impl(current_value: &mut String, add_value: &str) {
        current_value.push_str(add_value);
    }

    /// Method for external use — less flexible, but simple.
    pub fn add(&mut self, value: &str) {
        Self::add_impl(&mut self.current_value, value);
    }

    fn do_something(&mut self) {
        Self::add_impl(&mut self.current_value, &self.first_step);
    }

}

您的描述“……可以使用创建结构本身时定义的一些“常量”值来更新自身的数据结构……”表明您可能遇到比这个简单示例更复杂的情况。如果您有多个需要更新的可变字段(或者即使您确实想使用方法语法),您可以创建另一个struct包含正确的字段子集 - 那么方法如下do_something可以调用普通的&mut self内部结构上的方法。

struct FancyAdder {
    first_step: String,
    data: AdderData,
}

struct AdderData {
    current_value: String,
    ...
}

impl FancyAdder {
    fn do_something(&mut self) {
       // This borrows `self.data` mutably and `self.first_step` immutably.
       // No overlap.
       self.data.add(&self.first_step);
    }
}

impl AdderData {
    fn add(&mut self, value: &str) {
        self.current_value.push_str(value);
    }
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

使用结构本身的值更新结构给出:“不能借用`*self`作为可变的,因为它也被借用为不可变的” 的相关文章

随机推荐