2016-01-26 19 views
14

Tôi đang cố phát triển ứng dụng định tuyến thư. Tôi đã đọc các tài liệu chính thức của Rust và một số bài báo và nghĩ rằng tôi đã nhận được cách trỏ, sở hữu và mượn các công cụ nhưng nhận ra rằng tôi đã không.Không thể mượn nội dung mượn không thể thay đổi được vì có thể biến đổi

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 
    } 

} 

(Cũng có sẵn trên playground)

Tạo các lỗi:

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 

Ông có thể vui lòng giải thích lỗi và nó sẽ là tuyệt vời nếu bạn có thể cho tôi thực hiện đúng.

Trả lời

23

Đây là một bản tái tạo nhỏ hơn của vấn đề của bạn:

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

fn main() {} 

Nhiều lần, khi một cái gì đó dường như ngạc nhiên như thế này, nó là hữu ích để print out the types involved. Hãy in ra loại queue:

let mut q:() = self.data.get(&component); 
= note: expected type `()` 
      found type `&mut &std::vec::Vec<u8>` 

Chúng tôi có một tài liệu tham khảo có thể thay đổi một bất biến tham chiếu đến một Vec<u8>. Bởi vì chúng tôi có một tham chiếu bất biến với Vec, chúng tôi không thể sửa đổi nó! Thay đổi self.data.get thành self.data.get_mut thay đổi loại thành &mut &mut collections::vec::Vec<u8> và mã biên dịch.


Nếu bạn muốn thực hiện các khái niệm về "chèn hoặc cập nhật", bạn nên kiểm tra vào entry API, đó là hiệu quả hơn và súc tích.

Ngoài ra, Rust sử dụng snake_case để đặt tên phương thức, chứ không phải camelCase.

+0

Cảm ơn. Bây giờ tôi hiểu nó tốt hơn. Cảm ơn bạn đã tư vấn về các loại in, hóa ra rất hữu ích để khắc phục sự cố – dmgcodevil

+0

Liên kết dưới * in ra các loại có liên quan * vẫn có sẵn? Có một câu hỏi SO, nhưng tôi nghĩ rằng liên kết chỉ đến một số câu trả lời. – stej

+1

@stej liên kết là câu hỏi. Điều đó cho phép một câu trả lời tốt hơn để đi vào hoặc cho người thực hiện để chọn một câu trả lời khác nhau nếu tình hình là khác nhau. Trong trường hợp này, tôi đã sử dụng phiên bản "chỉ định cho bộ trống". – Shepmaster

Các vấn đề liên quan