在实现的函数 Rust 中为 self struct 赋值

Assign values to self struct inside implemented function Rust

我最近为了一个项目改用 Rust,但我很难处理可变和不可变的对象。

我遇到了一个问题,我需要将一个可变对象传递给我的一个特征的实现函数中的函数。我收到的错误如下:

error[E0596]: cannot borrow `self.volume_name` as mutable, as it is behind a `&` reference
   --> src/main.rs:107:40
    |
94  |     fn load_info(&self, name: &str) {
    |                  ----- help: consider changing this to be a mutable reference: `&mut self`
...
107 |         seek_read(&mut opened_file, 3, &mut self.volume_name).unwrap();
    |                                        ^^^^^^^^^^^^^^^^^^^^^ `self` is a `&` reference, so the data it refers to cannot be borrowed as mutable

我不知道如何修复这个错误,因为似乎每次尝试修复都会弹出另一个错误。我尝试创建一个新对象并将新对象设置为 self,但这也没有用,因为此函数中的 self 是一个引用,如果我将地址设置为相同,一旦我离开上下文,它就会消失,所以我得到另一个错误!记住,我来自C.

基本代码:

pub trait Filesystem {
   fn load_info(&self, name: &str);
}

pub struct Fat16 {
    pub volume_name: [u8; 8],
}

impl Default for Fat16 {
    fn default() -> Fat16 {
        Fat16 {
            volume_name: [0; 8],
        }
    }
}

impl Filesystem for Fat16 {
    fn load_info(&self, name: &str) {

        //I assume the file is a Fat16 volume, the checks are done before

        let mut opened_file = match File::open(&name) {
            Err(why) => panic!("couldn't open {}: {}", name, why),
            Ok(opened_file) => opened_file,
        };

        // ------------------------ VOLUME NAME ------------------------

        // Volume name starts at 3
        seek_read(&mut opened_file, 3, &self.volume_name).unwrap();

        match str::from_utf8(&self.volume_name) {
            Ok(v) => println!("Volume Name: {}", v),
            Err(e) => panic!("Invalid UTF-8 sequence: {}", e),
        };
        
        /*more code*/

求读函数:

pub fn seek_read(mut reader: impl Read + Seek, offset: u64, buf: &mut [u8]) -> io::Result<()> {
    reader.seek(SeekFrom::Start(offset))?;
    reader.read_exact(buf)?;
    Ok(())
}

self is a & reference, so the data it refers to cannot be borrowed as mutable

据推测,load_info 会将信息加载到 Filesystem 对象中。如果你想改变 self 的属性,它需要是可变的。

pub trait Filesystem {
   fn load_info(&mut self, name: &str);
                ^^^^
}

impl Filesystem for Fat16 {
    fn load_info(&mut self, name: &str) {
                 ^^^^
        let mut opened_file = match File::open(&name) {
            Err(why) => panic!("couldn't open {}: {}", name, why),
            Ok(opened_file) => opened_file,
        };

        seek_read(&mut opened_file, 3, &mut self.volume_name).unwrap();
                                       ^^^^

        match std::str::from_utf8(&self.volume_name) {
            Ok(v) => println!("Volume Name: {}", v),
            Err(e) => panic!("Invalid UTF-8 sequence: {}", e),
        };
    }
}