对于使用default表示形式的struct Asdf(i32);
,内存大小和对齐方式似乎与原始i32
原语相同。
有没有一种方法可以将Vec<Asdf>
和Vec<i32>
的内存相等性从Asdf
转换为i32
?理想的解决方案是,编译器和优化器在编译时检测到转换可以作为零成本强制转换,并在不再存在这种情况时退回到副本或引发编译器错误(例如,如果有人在Asdf
中添加第二个参数。
基于副本的安全解决方案
在IntoIter
上映射时,位于opt-level = 3
的优化程序不会删除副本。
fn convert(from: Vec<i32>) -> Vec<Asdf> {
from.into_iter().map(|p| Asdf(p)).collect()
}
不安全的解决方案
我知道可以通过使用Vec::from_raw_parts
或std::mem::transmute
来实现无副本转换。没有unsafe
代码,有什么方法可以做到这一点?
fn convert_unsafe(v_orig: Vec<i32>) -> Vec<Asdf> {
let mut v_orig = v_orig;
let v_from_raw = unsafe {
Vec::from_raw_parts(
v_orig.as_mut_ptr() as *mut Asdf,
v_orig.len(),
v_orig.capacity(),
)
};
std::mem::forget(v_orig);
v_from_raw
}
fn convert_transmute(v_orig: Vec<i32>) -> Vec<Asdf> {
unsafe { std::mem::transmute::<Vec<i32>, Vec<Asdf>>(v_orig) }
}