我有Vec<u8>
想要转换为(新类型)数组的(新类型)Vec
。我想不出我为什么不能重用现有分配的原因,所以这就是我想出的:
use std::mem::{size_of, transmute, ManuallyDrop};
// If I understand correctly, size_of::<u8; N>() == N and
// repr(transparent) ensures that for newtyped [u8; N] too.
#[derive(Debug)]
#[repr(transparent)]
struct Foo([u8; 4]);
#[derive(Debug)]
struct FooVec(Vec<Foo>);
impl From<Vec<u8>> for FooVec {
fn from(vec: Vec<u8>) -> Self {
// Prevent contents of vec being dropped.
let mut vec = ManuallyDrop::new(vec);
// Compute length of foovec and ensure that there aren't any leftover bytes.
let len = vec.len();
assert!(len % size_of::<Foo>() == 0);
let len = len / size_of::<Foo>();
// Compute capacity of foovec and ensure that there aren't any leftover allocated bytes.
let cap = if vec.capacity() % size_of::<Foo>() == 0 {
vec.capacity() / size_of::<Foo>()
} else {
let cap = vec.capacity();
let size = size_of::<Foo>();
vec.reserve_exact(size - (cap % size));
vec.capacity() / size
};
// Get pointer to contents of vec and transmute it to desired type.
let ptr = unsafe { transmute::<*mut u8, *mut Foo>(vec.as_mut_ptr()) };
// Construct foovec.
unsafe { FooVec(Vec::from_raw_parts(ptr, len, cap)) }
}
}
// Prints:
// [0, 1, 2, 3, 4, 5, 6, 7]
// FooVec([Foo([0, 1, 2, 3]), Foo([4, 5, 6, 7])])
fn main() {
let vec: Vec<u8> = vec![0, 1, 2, 3, 4, 5, 6, 7];
println!("{:?}", vec);
let foovec = FooVec::from(vec);
println!("{:?}", foovec);
}
这是执行此操作的正确方法吗?有安全方法可以做到这一点吗?