如何从原始指针创建一个 ?Sized 类型?
How do you create a ?Sized type from a raw pointer?
这是一个如何从原始指针转换 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
。
这是一个如何从原始指针转换 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
。