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· σημασία έχει πότε χρησιμοποιείται τελευταία φορά.