สนิม: ไม่สามารถสร้างโครงสร้างที่เก็บค่าและการอ้างอิงถึงค่าเหล่านี้ได้ [ซ้ำกัน]

ฉันสร้างโครงสร้างที่เก็บค่าและการอ้างอิงถึงสิ่งเหล่านั้น และยังสร้างวิธีการเพิ่มค่าและอายุการใช้งานที่ระบุด้วย ตัวอย่างรหัส:

struct Storage<'a> {
    owner :Vec<i32>,
    links :Vec<&'a i32>
}

impl<'a> Storage<'a> {
    fn new() -> Storage<'a> {
        Storage {owner: vec![], links: vec![]}
    }

    fn add_int(&mut self, x :i32) {
        self.owner.push(x);
        let len = self.owner.len();
        let ref_x = match self.owner.get(len-1) {
            Some(x) => x,
            None => panic!("ERROR")
        };
        self.links.push(ref_x);
        let ref_x = 0;
    }
}

fn main() {
    let mut store = Storage::new();
    store.add_int(1);
    store.add_int(2);
}

จากนั้นฉันได้รับข้อผิดพลาดของคอมไพเลอร์:

error[E0495]: cannot infer an appropriate lifetime for lifetime parameter in function call due to conflicting requirements
let ref_x = match self.owner.get(len-1) {                                                               
                             ^^^         

ฉันสามารถแก้ไขข้อผิดพลาดนี้และตั้งค่าเป็น self อายุการใช้งาน 'a สำหรับโครงสร้างได้ แต่ในกรณีนี้ self จะไม่ถูกลบแม้หลังจากเสร็จสิ้นวิธีการแล้วก็ตาม และเมื่อฉันพยายามเรียกใช้เมธอดนี้สองครั้ง ฉันได้รับข้อผิดพลาดต่อไปนี้:

error[E0499]: cannot borrow `store` as mutable more than once at a time

แต่ความขัดแย้งนี้จะแก้ไขได้อย่างไร?

และอาจมีวิธีที่ถูกต้องกว่านี้ใน Rust ในการจัดเก็บข้อมูลในโครงสร้างโดยอนุญาตให้เข้าถึงได้ไม่เฉพาะผ่านเจ้าของเท่านั้น


person arcanius    schedule 03.01.2019    source แหล่งที่มา
comment
ในทางเทคนิคแล้วเป็นไปได้ที่จะสร้างโครงสร้างแบบยืมตัวเองตลอดอายุการใช้งาน แต่โครงสร้างดังกล่าวไม่สามารถย้ายได้ (เพราะการย้ายจะทำให้การอ้างอิงภายในเป็นโมฆะ) และไม่สามารถยืมแบบเปลี่ยนแปลงได้ (เพราะเป็นการยืมอย่างถาวรไม่เปลี่ยนรูป) ดังนั้นจึงไม่ มักจะมีประโยชน์ในการทำเช่นนั้น วิธีที่ดีที่สุดในการดำเนินการต่อไปคือสร้าง links a Vec<usize> และจัดเก็บดัชนี (เช่น แทนที่จะยุ่งกับ ref_x แค่เขียน self.links.push(len - 1))   -  person trentcl    schedule 03.01.2019
comment
ขอบคุณ trentcl.   -  person arcanius    schedule 03.01.2019
comment
นี่เป็นตัวอย่างที่ดีเยี่ยมของ Rust ที่ช่วยรักษาสุขภาพจิตของคุณ ในภาษา C++ โค้ดของคุณจะถูกคอมไพล์และระเบิดในขณะรันไทม์ ปัญหา? เมื่อคุณใช้ Vec::push เวกเตอร์อาจมีพื้นที่ไม่เพียงพอ (ความจุเต็ม) ซึ่งในกรณีนี้เวกเตอร์จะจัดสรรอาร์เรย์ใหม่ (ใหญ่กว่า 2 เท่า) และย้ายองค์ประกอบทั้งหมดไปยังอาร์เรย์ใหม่นั้น น่าเสียดาย นั่นหมายความว่าการอ้างอิง (ตัวชี้) ไปยังองค์ประกอบเหล่านั้นในทันทีทันใดนั้น ห้อย: ชี้ไปที่หน่วยความจำที่ว่าง และนั่นเป็นพฤติกรรมที่ไม่ได้กำหนดไว้ และผลกระทบแปลกๆ ทุกชนิดสามารถเกิดขึ้นได้ :x   -  person Matthieu M.    schedule 03.01.2019