首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >不能将不可变的借用内容作为可变内容借用

不能将不可变的借用内容作为可变内容借用
EN

Stack Overflow用户
提问于 2016-01-26 09:41:33
回答 1查看 14.5K关注 0票数 22

我在试着开发一个消息路由应用。我已经阅读了Rust的官方文档和一些文章,并认为我知道指针,拥有和借用东西是如何工作的,但意识到我没有。

代码语言:javascript
复制
use std::collections::HashMap;
use std::vec::Vec;

struct Component {
    address: &'static str,
    available_workers: i32,
    lang: i32
}

struct Components {
    data: HashMap<i32, Vec<Component>>
}

impl Components {
    fn new() -> Components {
        Components {data: HashMap::new() }
    }

    fn addOrUpdate(&mut self, component: Component) -> &Components {
        if !self.data.contains_key(&component.lang) {

            self.data.insert(component.lang, vec![component]);
        } else {
            let mut q = self.data.get(&component.lang); // this extra line is required because of the error: borrowed value does not live long enough
            let mut queue = q.as_mut().unwrap();
            queue.remove(0);
            queue.push(component);
        }
        self
    }

}

(也可在playground上使用)

生成以下错误:

代码语言:javascript
复制
error: cannot borrow immutable borrowed content `**queue` as mutable
  --> src/main.rs:26:13
   |
26 |             queue.remove(0);
   |             ^^^^^ cannot borrow as mutable

error: cannot borrow immutable borrowed content `**queue` as mutable
  --> src/main.rs:27:13
   |
27 |             queue.push(component);
   |             ^^^^^ cannot borrow as mutable

你能解释一下错误吗?如果你能给我正确的实现,那就太好了。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2016-01-26 10:56:06

以下是您的问题的MCVE

代码语言:javascript
复制
use std::collections::HashMap;

struct Components {
    data: HashMap<u8, Vec<u8>>,
}

impl Components {
    fn add_or_update(&mut self, component: u8) {
        let mut q = self.data.get(&component);
        let mut queue = q.as_mut().unwrap();
        queue.remove(0);
    }
}

NLL之前的

代码语言:javascript
复制
error[E0596]: cannot borrow immutable borrowed content `**queue` as mutable
  --> src/lib.rs:11:9
   |
11 |         queue.remove(0);
   |         ^^^^^ cannot borrow as mutable

NLL之后的

代码语言:javascript
复制
error[E0596]: cannot borrow `**queue` as mutable, as it is behind a `&` reference
  --> src/lib.rs:11:9
   |
11 |         queue.remove(0);
   |         ^^^^^ cannot borrow as mutable

很多时候,当一些事情看起来像这样令人惊讶时,它对print out the types involved很有用。让我们打印出queue的类型

代码语言:javascript
复制
let mut queue: () = q.as_mut().unwrap();
代码语言:javascript
复制
error[E0308]: mismatched types
  --> src/lib.rs:10:29
   |
10 |         let mut queue: () = q.as_mut().unwrap();
   |                             ^^^^^^^^^^^^^^^^^^^ expected (), found mutable reference
   |
   = note: expected type `()`
              found type `&mut &std::vec::Vec<u8>`

我们有一个对Vec<u8>的不可变引用的可变引用。因为我们有一个对Vec的不可变引用,所以我们不能修改它!将self.data.get更改为self.data.get_mut会将类型更改为&mut &mut collections::vec::Vec<u8>,并编译代码。

如果您想实现“插入或更新”的概念,您应该签入entry API,它更高效、更简洁。

除此之外,Rust使用snake_case而不是camelCase来命名方法。

票数 35
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/35005704

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档