我正在尝试将Vec
of u32
s转换为Vec
of u8
s,最好是就地的,并且不需要太多的开销。
我的当前解决方案依赖于不安全的代码来重新构造Vec
。是否有更好的方法来做到这一点,与我的解决方案相关的风险是什么?
use std::mem;
use std::vec::Vec;
fn main() {
let mut vec32 = vec![1u32, 2];
let vec8;
unsafe {
let length = vec32.len() * 4; // size of u8 = 4 * size of u32
let capacity = vec32.capacity() * 4; // ^
let mutptr = vec32.as_mut_ptr() as *mut u8;
mem::forget(vec32); // don't run the destructor for vec32
// construct new vec
vec8 = Vec::from_raw_parts(mutptr, length, capacity);
}
println!("{:?}", vec8)
}
发布于 2022-07-19 17:54:43
这就是我如何使用位转换副本解决问题的方法。
它在我的x64机器上工作,但我不确定我是否对小/大的endianism做出了不安全的假设。
如果可以在不需要副本的情况下在内存中执行此强制转换,则运行时性能将更快,但我还没有弄清楚如何做到这一点。
/// Cast Vec<u32> to Vec<u8> without modifying underlying byte data
/// ```
/// # use fractals::services::vectors::vec_u32_to_u8;
/// assert_eq!( vec_u32_to_u8(&vec![ 0x12345678 ]), vec![ 0x12u8, 0x34u8, 0x56u8, 0x78u8 ]);
/// ```
#[allow(clippy::identity_op)]
pub fn vec_u32_to_u8(data: &Vec<u32>) -> Vec<u8> {
// TODO: https://stackoverflow.com/questions/72631065/how-to-convert-a-u32-array-to-a-u8-array-in-place
// TODO: https://stackoverflow.com/questions/29037033/how-to-slice-a-large-veci32-as-u8
let capacity = 32/8 * data.len() as usize; // 32/8 == 4
let mut output = Vec::<u8>::with_capacity(capacity);
for &value in data {
output.push((value >> 24) as u8); // r
output.push((value >> 16) as u8); // g
output.push((value >> 8) as u8); // b
output.push((value >> 0) as u8); // a
}
output
}
https://stackoverflow.com/questions/49690459
复制相似问题