Типы указателей
Все указатели являются явными значениями первого класса. Они могут быть перемещены или скопированы, сохранены в структуры данных и возвращены из функций.
Ссылки (& и &mut)
Syntax
ReferenceType → & Lifetime? mut? TypeNoBounds
Разделяемые ссылки (&)
Разделяемые ссылки указывают на память, которой владеет какое-то другое значение.
Когда создается разделяемая ссылка на значение, это предотвращает прямое изменение значения.
Внутренняя изменяемость предоставляет исключение для этого в определенных обстоятельствах.
Как следует из названия, может существовать любое количество разделяемых ссылок на значение.
Тип разделяемой ссылки записывается как &type или &'a type, когда нужно указать явное время жизни.
Копирование ссылки является “поверхностной” операцией:
она включает только копирование самого указателя, то есть указатели являются Copy.
Освобождение ссылки не влияет на значение, на которое она указывает, но ссылка на временное значение будет поддерживать его жизнь в течение области видимости самой ссылки.
Изменяемые ссылки (&mut)
Изменяемые ссылки указывают на память, которой владеет какое-то другое значение.
Тип изменяемой ссылки записывается как &mut type или &'a mut type.
Изменяемая ссылка (которая не была заимствована) является единственным способом доступа к значению, на которое она указывает, поэтому не является Copy.
Сырые указатели (*const и *mut)
Syntax
RawPointerType → * ( mut | const ) TypeNoBounds
Сырые указатели — это указатели без гарантий безопасности или жизнеспособности.
Сырые указатели записываются как *const T или *mut T.
Например, *const i32 означает сырой указатель на 32-битное целое число.
Копирование или сброс сырого указателя не влияет на жизненный цикл любого другого значения.
Разыменование сырого указателя является небезопасной операцией.
Это также может быть использовано для преобразования сырого указателя в ссылку путем перезаимствования (&* или &mut *).
Сырые указатели обычно не рекомендуются;
они существуют для поддержки взаимодействия с внешним кодом и написания производительных или низкоуровневых функций.
При сравнении сырых указателей они сравниваются по их адресу, а не по тому, на что они указывают. При сравнении сырых указателей на динамически sized типы также сравниваются их дополнительные данные.
Сырые указатели могут быть созданы напрямую с использованием &raw const для указателей *const и &raw mut для указателей *mut.
Умные указатели
Стандартная библиотека содержит дополнительные типы “умных указателей” помимо ссылок и сырых указателей.
Валидность битов
Несмотря на то, что указатели и ссылки похожи на usize в машинном коде, генерируемом на большинстве платформ,
семантика преобразования типа ссылки или указателя в не-указательный тип в настоящее время не определена.
Таким образом, может быть недопустимо преобразовывать тип указателя или ссылки, P, в [u8; size_of::<P>()].
Для тонких сырых указателей (т.е. для P = *const T или P = *mut T для T: Sized),
обратное направление (преобразование из целого числа или массива целых чисел в P) всегда допустимо.
Однако указатель, полученный таким преобразованием, не может быть разыменован (даже если T имеет нулевой размер).