DedSec Project

E0502 — DedSec Project

Rust E0502 — αλληλοεπικάλυψη mutable και immutable borrow Η σύγκρουση Η Rust επιτρέπει πολλαπλά read-only references ή ένα αποκλειστικό mutable reference, όχι ταυτόχρονα στο ίδιο…

Rust E0502 — αλληλοεπικάλυψη mutable και immutable borrow

Η σύγκρουση

Η Rust επιτρέπει πολλαπλά read-only references ή ένα αποκλειστικό mutable reference, όχι ταυτόχρονα στο ίδιο αντικείμενο. Το push σε Vec μπορεί να μεταφέρει το buffer, οπότε παλιά references θα ήταν άκυρα.

fn main() {
    let mut names = vec![String::from("Ada")];
    let first = &names[0];
    // names.push(String::from("Grace")); // E0502 αν first χρησιμοποιηθεί παρακάτω
    println!("{}", first);
    names.push(String::from("Grace")); // το immutable borrow έχει τελειώσει
    assert_eq!(names.len(), 2);
}

Δύο διακριτές φάσεις

Ολοκλήρωσε την ανάγνωση πριν αλλάξεις τη δομή. Μπορείς να φυλάξεις boolean αντί για reference:

fn add_if_missing(names: &mut Vec<String>, candidate: &str) {
    let exists = names.iter().any(|name| name == candidate);
    if !exists { names.push(candidate.to_owned()); }
}

Δοκιμές

Έλεγξε όνομα που υπάρχει και νέο όνομα. Φτιάξε σκόπιμο compile-fail όπου first χρησιμοποιείται μετά το push, έπειτα διόρθωσέ το χωρίς unsafe. Για ανεξάρτητα τμήματα slice μελέτησε split_at_mut. Το RefCell έχει runtime borrow rules· δεν είναι γενική λύση για κακοσχεδιασμένα lifetimes.

Αναφορά: https://doc.rust-lang.org/error_codes/E0502.html

Άσκηση με δείκτη θέσης αντί για reference

Φτιάξε let mut names = vec![String::from("Ada")];, κράτησε let first_index = 0;, κάνε names.push(String::from("Grace")); και μόνο μετά διάβασε &names[first_index]. Η έξοδος παραμένει Ada, επειδή ο ακέραιος index δεν είναι pointer στο ενδεχομένως μετακινημένο buffer. Αν χρειάζεται αμετάβλητο στιγμιότυπο της τιμής, το names[0].clone() δίνει δικό του String, αλλά κοστίζει allocation. Με non-lexical lifetimes ένα borrow που δεν χρησιμοποιείται μετά το push μπορεί να τελειώσει εγκαίρως. Μην υποθέτεις ότι κάθε δήλωση &names[0] πριν το push αποτελεί αυτόματα E0502· σημασία έχει πότε χρησιμοποιείται τελευταία φορά.