假设我保证(通过未指定的方式)拥有一个[*mut T; N]
包含N
有效和不相交的可变指针的类型数组,所有指针都带有lifetime 'a
。如何将其转换为可变引用数组[&'a mut T; N]
?
换句话说,如何实现此功能?
unsafe fn ptrs_to_refs<'a, T, const N: usize>(ptrs: [*mut T; N]) -> [&'a mut T; N] {
// What goes here?
}
我并不是特别在寻找使用分配步骤的实现(例如使用Vec
)。
由于min_const_generics
已在Rust 1.51中设置为稳定,因此该问题针对的是也具有的假设稳定Rust min_const_generics
。我正在寻找与这些要求兼容的答案,而不使用其他不稳定的功能。
例如,该功能array_map
可以简单地
unsafe fn ptrs_to_refs<'a, T, const N: usize>(ptrs: [*mut T; N]) -> [&'a mut T; N] {
arr.map(|ptr| unsafe { &mut *ptr })
}
但由于无法将其稳定在1.51(据我所知),因此我不希望使用它。
理想情况下,您只需std::mem::transmute
在这里使用,因为引用和指针具有相同的内存布局。不幸的是,std::mem::transmute
即使这两种类型具有相同的布局,也不适用于通用数组。但是,您可以使用union
此方法来解决此问题,因为使用#[repr(C)]
联合类似于transmute
:
#[repr(C)]
union Transmute<'a, T, const N: usize> {
ptr_arr: ManuallyDrop<[*mut T; N]>,
ref_arr: ManuallyDrop<[&'a mut T; N]>,
}
unsafe fn ptrs_to_refs<'a, T, const N: usize>(ptrs: [*mut T; N]) -> [&'a mut T; N] {
let u = Transmute::<'a, T, N> { ptr_arr: ManuallyDrop::new(ptrs) };
ManuallyDrop::into_inner(u.ref_arr)
}
您还可以使用std::mem::transmute_copy
,在这里可以有效地执行相同的操作:
unsafe fn ptrs_to_refs<'a, T, const N: usize>(ptrs: [*mut T; N]) -> [&'a mut T; N] {
std::mem::transmute_copy(&ptrs)
}
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句