什么是不推荐使用的std :: raw :: Repr的现代模拟?

时间:2018-09-28 17:04:26

标签: rust rust-obsolete

我正在浏览一些旧的(〜2014)Rust代码,并且看到了以下代码块:

fn compile(self, func:&UncompiledFunction<'a>) -> &'a Val {
    unsafe {
        use std::raw::Repr;
        use std::mem::transmute as cast;
        let slice = self.repr();
        let ty = <&'a str as Compile<'a>>::get_type();
        let structure = Val::new(func, &ty);
        let offset_data = cast::<_, usize>(&slice.data) - cast::<_, usize>(&slice);
        let offset_len = cast::<_, usize>(&slice.len) - cast::<_, usize>(&slice);
        func.insn_store_relative(structure, offset_data, func.insn_of(mem::transmute::<_, isize>(slice.data)));
        func.insn_store_relative(structure, offset_len, func.insn_of(slice.len));
        structure
    }
}

根据to the docsthis GitHub discussion std::raw::Reprstd::raw::Slice弃用了std::slice functions

作为只对std库有新手了解的人,我不确定如何翻译上述代码中的这些特定行:

let slice = self.repr(); // `self` here is a `static str`
let offset_data = cast::<_, usize>(&slice.data) - cast::<_, usize>(&slice);
let offset_len = cast::<_, usize>(&slice.len) - cast::<_, usize>(&slice);

我一直在翻阅documentation for Repr,希望能在std::slice家族中产生一些功能,但我对此一无所知。

我希望有人可以向我解释Repr的确切功能(用不同的语言)以及可能会更新的方法。

1 个答案:

答案 0 :(得分:3)

对于类型为x&[T]的{​​{1}}:

  • &str的替代项是x.repr().data
  • x.as_ptr()的替代项是x.repr().len
  • x.len()转换回std::raw::Slice&[T]的替代方法是&str(以及可选的std::slice::from_raw_parts)。

但是,这段代码不仅访问指针和长度,还使用了这些字段的地址来计算它们的偏移量,大概是以后做一些不安全/未经检查的内存读取或写入操作

没有帮助的答案是不要这样做。删除std::str::from_utf8_unchecked正是因为我们不想稳定std::raw::Slice&[T]的确切内存布局。如果完全有可能,请考虑重构代码以不执行这些未经检查的内存访问,而是执行例如将整个字符串替换为&str

实际的答案是,内存布局不太可能更改,如果您进行硬编码,则可能会没事:

std::str::from_utf8_unchecked(std::slice::from_raw_parts(new_pointer, new_len))