4 ms·
> Interesting - so essentially calling a "non-const" (mutable) method invalidates any existing references to the object, with this being implemented at compile
by School-Cotton 3y ago
> Interesting - so essentially calling a "non-const" (mutable) method invalidates any existing references to the object, with this being implemented at compile time by not allowing the mutable method to be called while other references are still alive ?
Yes, exactly.
> How exactly is this defined for something like index() which is returning a reference to a different type than the object itself, and where the declaration doesn't indicate that the referred to T is actually part of the parent object?
Only if they have the same lifetime (the 'a in my example). For example, imagine a function that gets an element of a vector and uses that to index into another vector. You might write it like this:
fn indirect_index<'a, 'b, T>(v1: &'a Vec<usize>, v2: &'b Vec<T>, i: usize) -> &'b T {
let j = v1[i];
&v2[j]
}
The returned value is not invalidated by any future mutations of the first vector, but only the second vector, since they share the lifetime parameter 'b.
> What happens in Rust if you attempt to use a reference to an object after the object lifetime has ended?
This is prevented at compile time by the borrow checker. E.g.:
// this takes ownership of the vec,
// and just lets it go out of scope
fn drop_vec<T>(_v: Vec<T>) {
}
fn main() {
let v = vec![1, 2, 3];
let x = &v[0];
drop_vec(v);
println!("{x}");
}
This program fails to compile with the following error:
error[E0505]: cannot move out of `v` because it is borrowed
--> src/main.rs:9:14
|
7 | let v = vec![1, 2, 3];
| - binding `v` declared here
8 | let x = &v[0];
| - borrow of `v` occurs here
9 | drop_vec(v);
| ^ move out of `v` occurs here
10 | println!("{x}");
| --- borrow later used here
- HarHarVeryFunny 3y agoThanks!