В Rust есть два основных вида ссылок:
&T): предоставляют доступ только для чтения.&mut T): позволяют изменять значение, на которое ссылаются.Правила:
Примеры синтаксиса:
fn read(val: &i32) { println!("{}", val); } fn write(val: &mut i32) { *val += 1; } let mut x = 5; read(&x); write(&mut x);
Вопрос: Можно ли создать две мутабельные ссылки на одну переменную в разных областях видимости одной функции?
Ответ: Нет, даже если ссылки создаются в разных блоках, область видимости для анализа заимствований охватывает всю функцию или переменную, если компилятор не может точно доказать, что ссылки не пересекаются. Это часто выливается в ошибки компиляции:
let mut x = 10; let r1 = &mut x; { let r2 = &mut x; // ошибка! }
История
В разработке парсера разработчик попытался хранить одновременно мутабельную и немутируемую ссылку на один буфер для оптимизации чтения и записи. В результате код не компилировался, а после "обхода" правила через unsafe появились баги утечки данных.
История
На старте проекта по обработке данных один из участников не делал "reanalyze borrow checker" для сложного кода с вложенными областями. В результате, из-за пересекающихся ссылок вылезла классическая "cannot borrow as mutable because it's also borrowed as immutable"-ошибка без явного указания в исходном коде места проблемы.
История
В мультитрединговом коде использовали обычные ссылки для доступа к разделяемым данным. При попытке изменить данные в параллельных потоках получали неожиданные ошибки компилятора и гонки данных при обходе borrow checker через небезопасный код.