Borrowing (заимствование) в Rust — это механизм временного "одалживания" переменной через ссылки. Rust различает немутируемое заимствование (&T) и мутабельное (&mut T). Одновременно может существовать сколько угодно немутируемых ссылок, но только одна мутабельная. Не допускается одновременное существование мутабельных и немутируемых ссылок на один и тот же объект.
Это правило гарантирует отсутствие data race на этапе компиляции и делает Rust безопасным для конкурентного программирования.
Пример:
let mut value = 5; let r1 = &value; let r2 = &value; // let r3 = &mut value; // ОШИБКА: нельзя создавать &mut пока есть & println!("{} {}", r1, r2); // r3 запрещен до конца области видимости r1/r2
Вопрос: Можно ли в одной области видимости создать одну &mut ссылку и сколько угодно & ссылок на один объект?
Типичный неверный ответ: Да, но только если они не пересекаются по времени жизни.
Правильный ответ: Одновременно не может существовать мутабельная и немутируемая ссылка на один объект (даже если обращения к ним не пересекаются статически в коде), пока одна жива — другие запрещены. Безопасность проверяет borrow checker.
Пример:
let mut x = 10; let y = &x; let z = &mut x; // Ошибка, y еще в области видимости println!("{}", y); // y нужен позже
История
В крупном проекте с параллельной обработкой данных разработчик решил использовать немутируемые ссылки на вектор, а затем попытался получить мутабельную для сортировки. Код работал в тесте, но перестал компилироваться после рефакторинга, т.к. расширился срок жизни немутируемых ссылок.
История
Во внутреннем сервисе изменяли структуру через &mut, сохраняя при этом ссылки на поля для дальнейшей отправки в другой поток. Возникла гонка данных и crash из-за несоблюдения borrow правил — Rust защищает от этого только на этапе компиляции, но ошибки были в unsafe-блоках, где гарантии сняты.
История
Некорректное документирование API: библиотека принимала одновременно & и &mut на разные поля структуры, но из-за aliasing нарушалась инвариантность и возникали трудноуловимые баги с сервисами, интегрировавшими эту библиотеку.