Voici un exemple de transmuter un type Sized
d'un pointeur brut:Comment créer un type? Sized à partir d'un pointeur brut?
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);
}
Cependant, pour ma demande, je veux être en mesure d'obtenir un type ?Sized
au lieu d'un type Sized
. Cependant, cela ne fonctionne pas:
unsafe fn get_type2<'a, T: ?Sized>(p: *const u8) -> &'a T {
mem::transmute(p)
}
Il échoue avec ce message d'erreur:
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)
|> ^^^^^^^^^^^^^^
J'ai essayé de lui donner un &[u8]
(pointeur de la graisse) en le convertissant en utilisant std::slice::from_raw_parts
, mais il échoue avec à peu près le même message d'erreur.
l'ai obtenu, donc je suppose que le compilateur gère magiquement tout cela pour le cas d'utilisation normal? (qui est ce que cela signifiait que «Sized» est un «compilateur intrinsèque ...) - aussi vous avez dit«! Sized »et je pense que vous vouliez dire«? Sized » – vitiral
@cloudformdesign: Je voulais dire«! Sized ». 'Sized' signifie taille,'! Sized' signifie pas dimensionné (mais ne peut pas être réellement utilisé comme une limite) et '? Sized' signifie taille peut-être.En ce qui concerne les conversions de gestion du compilateur: en effet, le compilateur ne fait qu'emballer/décompresser Notez que les deux méthodes 'raw :: TraitObject' et' raw :: Slice' sont instables comme principe pour permettre l'évolution de la représentation sous-jacente, et resteront probablement instables "pour toujours" car Rust n'est pas une parenté sur un commit stable ABI –
génial! Merci pour le bon aperçu – vitiral