我正在浏览一些旧的(〜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 docs和this GitHub discussion std::raw::Repr
和std::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
的确切功能(用不同的语言)以及可能会更新的方法。
答案 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))