Насколько я понимаю, стандартный (единственный?) способ сделать нулевой указатель в Rust — это std::ptr::null
.
Однако эта функция объявлена следующим образом.
pub const fn null<T>() -> *const T
В этом объявлении неявно предполагается, что T
имеет фиксированный размер (иначе это было бы T: ?Sized
). Как следствие, эту функцию невозможно использовать, например, с *const str
или *const [u32]
. тестировать на игровой площадке
Есть ли веская причина для исключения неразмерных типов? Что плохого в желании создать нуль *const str
?
1 ответ
Указатель на неразмерный тип — это толстый указатель с двумя компонентами: указатель и метаданные типа (длина для срезов и указатель vtable для трейт-объектов; в будущем Rust может разрешить другие виды метаданных). null
подразумевает значение только для части указателя; нет очевидного выбора для другого значения. (Вы можете подумать, что 0 является очевидным для длины нулевого указателя слайса, и я вижу аргумент, но если указатель нулевой, вряд ли имеет значение, сколько там вещей; вы все равно не можете разыменовать его, поэтому размер 0 не требуется для обеспечения безопасности.)
Невозможно создать нулевой указатель на трейт-объект, но начиная с Rust 1.42 вы можете использовать ptr::slice_from_raw_parts
для создания нулевого указателя на срез. Предположим, что длина среза равна 0:
use std::ptr;
fn main() {
let p: *const [u32] = ptr::slice_from_raw_parts(ptr::null(), 0);
println!("{:?}", p);
}
Для str
нет эквивалентной функции, но вы можете создать ее, создав null *const [u8]
и приведя его к as
.
Эта функция (или связанная с ней функция slice_from_raw_parts_mut
) — единственный способ правильно создать нулевой указатель на срез. Обычный способ получить необработанный указатель — привести ссылку, но ссылки никогда не могут быть нулевыми.
Похожие вопросы
Новые вопросы
pointers
Типы данных для «указания» на другие значения: значение указателя — это адрес памяти, где хранится указываемое значение. Этот тег следует использовать для вопросов, связанных с использованием указателей, а не ссылок. Распространенными языками программирования, использующими указатели, являются C, C++, Go, а также языки ассемблера и промежуточного представления; использовать определенный языковой тег. Другие полезные теги должны описывать, на что указывает указатель (например, функция, структура и т. д.).
slice_from_raw_parts
безопасен - причина в том, что его почти невозможно использовать, поскольку функции принимают ссылку, а не указатель, иunsafe
требуется для перехода от указателя к ссылке.slice_from_raw_parts
может привести к "неправильному"*const [T]
из "хорошего"*const T
, если предоставлен неправильный размер, поэтому я думаю, что это должно быть помечено как небезопасное...unsafe
. Да, он может произвести неправильный*const [T]
из хорошего*const T
... но вы не можете использовать этот*const [T]
безunsafe
, чтобы преобразовать его в&[T]
или&mut [T]
.null
? Нуль? Один? Что-то произвольное? Предоставление метаданных предполагает некоторое намерение разыменовать указатель, что явно неверно, поэтому я утверждаю, что нулевой указатель среза (или нулевой указатель трейт-объекта), вероятно, является следствием ошибки проектирования. В любом случае вам, вероятно, следует использоватьOption<&[T]>
вместо*const [T]
.