はここで生のポインタから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)
}
それは、このエラーメッセージで失敗します。私はstd::slice::from_raw_parts
を使用して、それを変換することによってそれを&[u8]
(ファットポインタ)を与えることを試みたが、それが失敗した
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)
|> ^^^^^^^^^^^^^^
かなり同じエラーメッセージが表示されます。
だから、コンパイラは普通のユースケースのすべてのことを魔法のように扱いますと思いますか? (それは '' Sized''がコンパイラ組み込みであることを意味しています...) - 'Sized'と' 'Sized'を意味すると思います。 – vitiral
@cloudformdesign:私は'!Sized'を意味しました。 'Sized'はサイズを意味し、'!Sized'はサイズではない(実際にはバインドとして使用することはできません)、 '?Sized'は多分サイズを意味します。 'raw :: TraitObject'と' raw :: Slice'の両方が根本的な表現の進化を可能にする原則として不安定であり、おそらくRustが安定したABI。 –
すごい! – vitiral