Почему приведённый Rust‑код не компилируется, какая часть правил владения и заимствования нарушается, и как правильно переписать пример, чтобы сохранить безопасный доступ и при этом добавить элемент в вектор после получения ссылки: fn main() { let mut v = vec![1,2,3]
Почему не компилируется (суть): - Когда вы берёте ссылку `let r = &v[0];`, создаётся неизменяемая ссылка. - Вызов `v.push(...)` требует `&mut self` — мутабельной ссылки на `v`. - Правило владения/заимствования: нельзя иметь одновременно живую неизменяемую и мутабельную ссылку на одни и те же данные. Также `push` может перераспределить память в `Vec` и сделать ссылку недействительной. Иначе: нарушается правило «нельзя одновременно immutable borrow и mutable borrow». Пример исходного состояния: вектор {1,2,3}\{1,2,3\}{1,2,3} и попытка взять ссылку, а потом сделать `push(4)` — не скомпилируется. Как правильно (несколько безопасных подходов) 1) Ограничить время жизни ссылки (блоком): fn main() { let mut v = vec![1, 2, 3]; { let r = &v[0]; println!("{}", r); } // r выходит из области видимости здесь v.push(4); println!("{:?}", v); } 2) Скопировать значение, если тип Copy (для чисел): fn main() { let mut v = vec![1, 2, 3]; let x = v[0]; // копия значения v.push(4); println!("x = {}, v = {:?}", x, v); } 3) Сохранить индекс, а обращаться после изменения: fn main() { let mut v = vec![1, 2, 3]; let idx = 0; v.push(4); println!("{}", v[idx]); } Коротко о числах: добавляем элемент 4 \,4\,4 к вектору {1,2,3}\{1,2,3\}{1,2,3}. Выберите подходящий вариант: (1) — если нужен доступ по ссылке до изменения; (2)/(3) — если можно обойтись копией или индексом.
- Когда вы берёте ссылку `let r = &v[0];`, создаётся неизменяемая ссылка.
- Вызов `v.push(...)` требует `&mut self` — мутабельной ссылки на `v`.
- Правило владения/заимствования: нельзя иметь одновременно живую неизменяемую и мутабельную ссылку на одни и те же данные. Также `push` может перераспределить память в `Vec` и сделать ссылку недействительной.
Иначе: нарушается правило «нельзя одновременно immutable borrow и mutable borrow».
Пример исходного состояния: вектор {1,2,3}\{1,2,3\}{1,2,3} и попытка взять ссылку, а потом сделать `push(4)` — не скомпилируется.
Как правильно (несколько безопасных подходов)
1) Ограничить время жизни ссылки (блоком):
fn main() {
let mut v = vec![1, 2, 3];
{
let r = &v[0];
println!("{}", r);
} // r выходит из области видимости здесь
v.push(4);
println!("{:?}", v);
}
2) Скопировать значение, если тип Copy (для чисел):
fn main() {
let mut v = vec![1, 2, 3];
let x = v[0]; // копия значения
v.push(4);
println!("x = {}, v = {:?}", x, v);
}
3) Сохранить индекс, а обращаться после изменения:
fn main() {
let mut v = vec![1, 2, 3];
let idx = 0;
v.push(4);
println!("{}", v[idx]);
}
Коротко о числах: добавляем элемент 4 \,4\,4 к вектору {1,2,3}\{1,2,3\}{1,2,3}.
Выберите подходящий вариант: (1) — если нужен доступ по ссылке до изменения; (2)/(3) — если можно обойтись копией или индексом.