下面是一个如何从原始指针转换 Sized
类型的示例:
use std::mem;
#[derive(Eq, PartialEq)]
#[repr(packed)]
struct Bob {
id: u32,
age: u32,
}
unsafe fn get_type<'a, T: Sized>(p: *const u8) -> &'a T {
mem::transmute(p)
}
#[test]
fn it_works() {
let bob = Bob {
id: 22,
age: 445,
};
let bob2: &Bob = unsafe {
let ptr: *const u8 = mem::transmute(&bob);
get_type(ptr)
};
assert_eq!(&bob, bob2);
}
但是,对于我的应用程序,我希望能够获得 ?Sized
类型而不是 Sized
类型。但是,这不起作用:
unsafe fn get_type2<'a, T: ?Sized>(p: *const u8) -> &'a T {
mem::transmute(p)
}
失败并显示此错误消息:
error: transmute called with differently sized types: *const u8 (64 bits) to &'a T (pointer to T) [--explain E0512]
--> src/main.rs:2:9
|>
2 |> mem::transmute(p)
|> ^^^^^^^^^^^^^^
我试图通过使用 std::slice::from_raw_parts
转换它来给它一个 &[u8]
(胖指针),但它几乎失败了同样的错误信息。
最佳答案
由于错误消息中引用的原因,您实际上不能。
Rust 引用可以是指针大小的(对于 Sized
类型)或更大(对于 !Sized
类型)。例如,如果 Trait
是一个特征,则 &Trait
引用实际上是两个字段,由 std::raw::TraitObject
定义。 .
因此,为了形成对未确定大小类型的引用,您必须:
- 准确识别它是哪种类型的未调整大小的类型(特征?切片?...)
- 选择正确的表示(
std::raw::TraitObject
,std::raw::Slice
, ...)
然后你必须填写空白(不仅仅是一个指针)。
因此,除非您可以将函数限制为生成 &T where T: Sized
,否则您不能只将原始指针转换为 &T
。
关于pointers - 如何从原始指针创建一个 ?Sized 类型?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39186185/