什么是已弃用的 std::raw::Repr 的现代类比?
What is a modern analog to the deprecated std::raw::Repr?
我正在查看一些旧的 (~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 and this GitHub discussion std::raw::Repr
and std::raw::Slice
have been deprecated in favor of 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
到底做了什么(用不同的语言)以及更新的方法可能是什么。
对于 &[T]
或 &str
类型的 x
:
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
)。
然而,这段代码不仅访问指针和长度,它还获取这些字段的 地址 来计算它们的偏移量,大概是为了稍后做一些 unsafe/unchecked内存读取或写入。
没有帮助的答案是不要这样做。 std::raw::Slice
被删除正是因为我们不想稳定 &[T]
和 &str
的确切内存布局。如果这完全可行,请考虑重构代码以不执行这些未经检查的内存访问,而是例如用 std::str::from_utf8_unchecked(std::slice::from_raw_parts(new_pointer, new_len))
.
替换整个字符串
实际的答案是内存布局不太可能改变,如果你硬编码你可能没问题:
let offset_data = 0;
let offset_len = std::mem::size_of::<usize>();
我正在查看一些旧的 (~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 and this GitHub discussion std::raw::Repr
and std::raw::Slice
have been deprecated in favor of 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
到底做了什么(用不同的语言)以及更新的方法可能是什么。
对于 &[T]
或 &str
类型的 x
:
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
)。
然而,这段代码不仅访问指针和长度,它还获取这些字段的 地址 来计算它们的偏移量,大概是为了稍后做一些 unsafe/unchecked内存读取或写入。
没有帮助的答案是不要这样做。 std::raw::Slice
被删除正是因为我们不想稳定 &[T]
和 &str
的确切内存布局。如果这完全可行,请考虑重构代码以不执行这些未经检查的内存访问,而是例如用 std::str::from_utf8_unchecked(std::slice::from_raw_parts(new_pointer, new_len))
.
实际的答案是内存布局不太可能改变,如果你硬编码你可能没问题:
let offset_data = 0;
let offset_len = std::mem::size_of::<usize>();