【问题标题】:Assign values to self struct inside implemented function Rust在实现的函数 Rust 中为 self struct 赋值
【发布时间】:2021-04-25 07:09:48
【问题描述】:

我最近为一个项目切换到 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*/

Seek 读取函数:

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(())
}

【问题讨论】:

  • 如果将签名更改为fn load_info(&amp;mut self, name: &amp;str)会怎样?
  • 帮助:考虑阅读编译器建议

标签: rust immutability traits mutable


【解决方案1】:

self 是一个&amp; 引用,因此它所引用的数据不能作为可变数据借用

大概load_info 会将信息加载到文件系统对象中。如果你想改变 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),
        };
    }
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2015-07-09
    • 2020-07-04
    • 1970-01-01
    • 1970-01-01
    • 2014-10-09
    • 1970-01-01
    • 2017-11-11
    相关资源
    最近更新 更多