Let me preface with saying that I m actively looking into other options than transmute
, I was just suprised that transmute
doesn t compile in this case.
Im在Builder
上工作的是图书馆,这些图书馆在编汇出田地时进行核对。 为此,使用一般体。 我谈的是基本内容,但我试图增加一个特点,因为我正在研究<条码>译明<>。
如果我使用<代码>transmute,则一套装置的例子如下:
#[derive(Builder)]
pub struct Foo<const SIZE: usize> {
bar: [usize; SIZE],
}
// Just the setter part of the macro expansion:
impl<const SIZE: usize> FooBuilder<SIZE, false> {
pub fn bar(mut self, bar: [usize; SIZE]) -> FooBuilder<SIZE, true> {
self.data.bar = Some(bar);
unsafe { std::mem::transmute(self) }
}
}
但是,转口工作就是这样。 <代码>SIZE完全相同,booleant对基本数据没有任何影响,但我仍然认为:
cannot transmute between types of different sizes, or dependently-sized types
source type: `test::const_generic::FooBuilder<SIZE, false>` (size can vary because of [usize; SIZE])
target type: `test::const_generic::FooBuilder<SIZE, true>` (size can vary because of [usize; SIZE])
我很奇怪的是,这一限制为何存在。 谁能向我解释这一点?
// simplified macro expansion:
pub struct Foo<const SIZE: usize> {
bar: [usize; SIZE],
}
pub struct FooData<const SIZE: usize> {
pub bar: Option<[usize; SIZE]>,
}
impl<const SIZE: usize> Builder for Foo<SIZE> {
type Builder = FooBuilder<SIZE, false>;
fn builder() -> FooBuilder<SIZE, false> {
self::Builder::new()
}
}
pub struct FooBuilder<const SIZE: usize, const __BUILDER_CONST_0: bool> {
data: FooData<SIZE>,
}
impl<const SIZE: usize> FooBuilder<SIZE, false> {
pub fn new() -> FooBuilder<SIZE, false> {
data: FooData<SIZE> {
bar: None,
}
}
}
impl<const SIZE: usize> FooBuilder<SIZE, false> {
pub fn bar(mut self, bar: [usize; SIZE]) -> FooBuilder<SIZE, true> {
self.data.bar = Some(bar);
unsafe { std::mem::transmute(self) }
// ^ Should work, because the value of `__BUILDER_CONST_0` has no influence
// on the layout of the struct, and `SIZE` is identical
}
}
impl<const SIZE: usize> FooBuilder<SIZE, true> {
pub fn build(self) -> Foo<SIZE> {
Foo<SIZE> {
bar: self.data.bar.unwrap()
}
}
}
Btw,实际设计体看得更像以下,在添加新的特征时,我刚刚开始讨论一些过错的终身问题(使用<条码>.impl AsRef<T>作为一套固定投入类型)。
impl<const SIZE: usize> FooBuilder<SIZE, false> {
pub fn bar(self, bar: [usize; SIZE]) -> FooBuilder<SIZE, true> {
let mut data = self.data;
data.bar = Some(bar);
FooBuilder { data }
}
}