为什么将 `ptr::write` 与 `MaybeUninit` 的数组一起使用?
Why use `ptr::write` with arrays of `MaybeUninit`s?
在标准库中,documentation展示了如何实例化数组
MaybeUninit
s:
let arr: [MaybeUninit<T>; N] =
MaybeUninit::uninit().assume_init();
我们知道这是安全的,因为 MaybeUninit
的合约允许未初始化的值。接下来我们被要求使用 ptr::write(value)
来初始化每个元素。但这需要再次 unsafe
代码。我们也知道覆盖 MaybeUninit
是安全的,因为它不会 drop
任何东西。那么为什么不像 arr[i] = MaybeUninit::new(value)
那样覆盖它呢?
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)
允许在没有 unsafe 关键字的情况下覆盖值并且 这是一个完美定义的行为。
你忘记的是 MaybeUninit
并不是真的在这里使用 仅 在 Rust 中,除非在极少数情况下,Rust 不需要它。我们主要在处理 ffi 时使用它,所以这个例子并不是真正的单词用例。所以它看起来很奇怪。在这里,作者可能想模拟一个真实的案例,其中数组将通过使用原始指针在 Rust 之外初始化。
在标准库中,documentation展示了如何实例化数组
MaybeUninit
s:
let arr: [MaybeUninit<T>; N] =
MaybeUninit::uninit().assume_init();
我们知道这是安全的,因为 MaybeUninit
的合约允许未初始化的值。接下来我们被要求使用 ptr::write(value)
来初始化每个元素。但这需要再次 unsafe
代码。我们也知道覆盖 MaybeUninit
是安全的,因为它不会 drop
任何东西。那么为什么不像 arr[i] = MaybeUninit::new(value)
那样覆盖它呢?
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)
允许在没有 unsafe 关键字的情况下覆盖值并且 这是一个完美定义的行为。
你忘记的是 MaybeUninit
并不是真的在这里使用 仅 在 Rust 中,除非在极少数情况下,Rust 不需要它。我们主要在处理 ffi 时使用它,所以这个例子并不是真正的单词用例。所以它看起来很奇怪。在这里,作者可能想模拟一个真实的案例,其中数组将通过使用原始指针在 Rust 之外初始化。