На основании комментария Stargateur вы можете использовать некоторые комбинации repr(C)
структуры и объединения. Из-за некоторых ограничений на union
мы требуем, чтобы базовые типы реализовали Copy
.
#[repr(C)]
union COptionEnum<T>
where
T: Copy,
{
value: T,
none: (),
}
#[repr(C)]
struct COption<T>
where
T: Copy,
{
discriminant: u32,
value: COptionEnum<T>,
}
Однако они не особенно эргономичны c, поэтому, чтобы облегчить боль, вы можете предоставить преобразования в и с Option
. Они выглядят так:
impl<T> From<Option<T>> for COption<T>
where
T: Copy,
{
fn from(v: Option<T>) -> COption<T> {
match v {
None => COption {
discriminant: 0,
value: COptionEnum { none: () },
},
Some(v) => COption {
discriminant: 1,
value: COptionEnum { value: v },
},
}
}
}
impl<T> From<COption<T>> for Option<T>
where
T: Copy,
{
fn from(v: COption<T>) -> Option<T> {
match v.discriminant {
0 => None,
1 => Some(unsafe { v.value.value }),
_ => panic!("Invalid COption"),
}
}
}
Наконец, вы можете использовать их относительно безболезненно.
#[repr(C)]
#[derive(Copy, Clone)]
struct AType {
a: i32,
b: u64,
}
fn main() {
let v1 = Some(AType { a: 1, b: 2 });
let cv1: COption<AType> = v1.into();
let w1: Option<AType> = cv1.into();
}
Полная копия находится на игровой площадке