Повторное заимствование
Повторное заимствование (reborrow) - это создание новой ссылки на данные
через уже существующую ссылку. Когда у вас есть изменяемая ссылка
&mut T, вы можете повторно заимствовать её как неизменяемую
&T или как другую изменяемую ссылку. Это позволяет передавать
ссылку в функции или методы, не перемещая её и не теряя владение.
Повторное заимствование происходит автоматически в большинстве случаев
благодаря неявному приведению типов.
Ключевое отличие повторного заимствования от перемещения (move) заключается в том, что исходная ссылка остаётся действительной после создания новой ссылки. Компилятор автоматически вставляет повторное заимствование, когда видит, что ссылка используется в контексте, требующем ссылку с меньшим временем жизни или менее строгими правами доступа.
Синтаксис
// Неявное повторное заимствование
let r1 = &mut value;
let r2 = &*r1; // повторное заимствование как неизменяемая ссылка
// Явное повторное заимствование
let r3 = &mut *r1; // повторное заимствование как изменяемая ссылка
Пример
Давайте рассмотрим пример, где изменяемая ссылка повторно заимствуется как неизменяемая:
fn main()
{
let mut value = 5;
let r1 = &mut value;
let r2 = &*r1;
println!("{}", r2);
*r1 = 10;
println!("{}", r1);
}
Результат выполнения кода:
5
10
Пример
Давайте передадим изменяемую ссылку в функцию, которая принимает неизменяемую ссылку, используя повторное заимствование:
fn print_value(val: &i32)
{
println!("{}", val);
}
fn main()
{
let mut value = 42;
let r1 = &mut value;
print_value(&*r1);
print_value(r1);
*r1 = 100;
println!("{}", r1);
}
Результат выполнения кода:
42
42
100
Пример
Давайте рассмотрим пример с несколькими повторными заимствованиями изменяемой ссылки:
fn main()
{
let mut value = 1;
let r1 = &mut value;
{
let r2 = &mut *r1;
*r2 = 2;
println!("{}", r2);
}
{
let r3 = &mut *r1;
*r3 = 3;
println!("{}", r3);
}
println!("{}", r1);
}
Результат выполнения кода:
2
3
3
Смотрите также
-
механизм
borrowing,
который позволяет временно заимствовать данные без передачи владения -
механизм
mut-borrow,
который позволяет создавать изменяемые ссылки на данные -
механизм
immut-borrow,
который позволяет создавать неизменяемые ссылки на данные -
правила
borrow-rules,
которые регулируют одновременное существование ссылок