Ссылки
Ссылка — это переменная, которая “ссылается” на данные, хранимые в другой переменной.
Для создания ссылки на значение, хранимое в переменной, используется оператор &.
let переменная: Тип = значение;
let ссылка: &Тип = &переменная;
При этом тип ссылки будет &тип_изначальной_переменной.
Например:
fn main() {
let a: i32 = 5;
let ref_a: &i32 = &a;
println!("Value in a is {}", *ref_a); // Value in a is 5
}
Оператор * в выражении *ref_a используется для получения значения, на которое ссылается ссылка.
Ссылки, как и переменные, по умолчанию являются немутабельными, т.е. с их помощью можно читать значение оригинальной переменной, но не изменять его. Чтобы создать мутабельную ссылку, нужно вместо & использовать &mut. Разумеется, мутабельную ссылку можно получить только для мутабельной переменной:
fn main() {
let mut a: i32 = 5;
let ref_a: &mut i32 = &mut a;
*ref_a = 99;
println!("Value in a is {}", *ref_a); // Value in a is 99
}
Note
В отличие от указателей в C, которые являются физическим типом данных, т.е. ячейкой в памяти, в которой хранится адрес, ссылка в Rust является скорее семантической сущностью. То есть в большинстве случаев создание ссылки в коде не приводит к созданию дополнительных сущностей в памяти программы: компилятор просто подменяет взаимодействие с ссылкой на взаимодействие со значением непосредственно. При этом на уровне кода программы ссылка ведёт себя так, словно это физический “указатель” на данные, хранимые в другой переменной.
В Rust ссылки являются безопасными: компилятор отслеживает время жизни ссылок относительно времени жизни переменных, на чьи данные они указывают. При попытке сослаться на данные, принадлежащие уже уничтоженной переменной, компилятор выдаст ошибку.
Мы поговорим подробнее о ссылках в главе Владение, а также в главе Лайфтаймы.