有什么方法可以从Vec <T>安全地转换为Vec <NewtypeOfT>而不复制向量的内容吗?

时间:2019-11-04 21:02:52

标签: rust

对于使用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_partsstd::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) }
}

0 个答案:

没有答案