Зачем использовать `ptr :: write` с массивами` MaybeUninit`s? - PullRequest
10 голосов
/ 12 июля 2019

В стандартной библиотеке документация показывает, как создавать массивы MaybeUninit s:

let arr: [MaybeUninit<T>; N] =
    MaybeUninit::uninit().assume_init();

Мы знаем, что это безопасно, поскольку контракт MaybeUninit допускаетнеинициализированные значения.Далее нас просят использовать ptr::write(value) для инициализации каждого элемента.Но для этого требуется код unsafe еще раз.Мы также знаем, что перезапись MaybeUninit безопасна, потому что ничего не делает drop.Так почему бы просто не переписать его как arr[i] = MaybeUninit::new(value)?

1 Ответ

1 голос
/ 12 июля 2019

let arr: [MaybeUninit<T>; N] = MaybeUninit::uninit().assume_init(); - это просто ярлык.

arr[i] = MaybeUninit::new(value), в вашем примере arr[i] - это MaybeUninit, поэтому ваш вопрос касается того, какой стиль использовать для преобразования вектора.Вы также можете сделать arr[i].write(value), который на самом деле не меняется на практике, но это требует каждую ночь, почему док не использует его.Но вы правы arr[i] = MaybeUninit::new(value) разрешить переопределять значение тоже без небезопасного ключевого слова, а это совершенно определенное поведение .

То, что вы забыли, это то, что MaybeUninit на самом деле не здесь, чтобы бытьиспользуется только внутри Rust, за исключением очень небольшого количества случаев, Rust не нужен.Мы в основном используем его, когда имеем дело с ffi, так что пример не является реальным вариантом использования слова.Так что это может выглядеть странно.Здесь автор, вероятно, хочет эмулировать случай реального слова, где массив будет инициализироваться вне Rust, используя необработанный указатель.

...