以下是如何从原始指针转换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)
|> ^^^^^^^^^^^^^^
我试图通过使用&[u8]
转换它来给它一个std::slice::from_raw_parts
(胖指针),但它失败了几乎相同的错误消息。
答案 0 :(得分:7)
您实际上不能出于错误消息中引用的原因。
Rust引用可以是指针大小(对于Sized
类型)或更大(对于!Sized
类型)。例如,如果Trait
是特征,则&Trait
引用实际上是std::raw::TraitObject
定义的两个字段。
因此,为了形成对unsized类型的引用,您必须:
std::raw::TraitObject
,std::raw::Slice
,...)然后你必须填补空白(不仅仅是一个指针)。
因此,除非您可以将函数限制为生成&T where T: Sized
,否则您不能将原始指针转换为&T
。