English 中文(简体)
为什么会 st:在已知两种类型的记忆完全相同的情况下,转播不成工作?
原标题:Why does std::mem::transmute not work when both types are known to have the exact same memory layout?

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 }
    }
}
问题回答

汇编者的分析限制性太大。 即便我们能够证明规模是平等的,也不允许任何依赖动态规模的变迁。

然而,请注意,就你的情况而言,转口是不正确的:你需要添加<条码>第[条][(透明)]





相关问题
Delphi: generics and is -operator problem

Based on an earlier post, I ve written the following code. Please excuse the verbosity of this post. I believe it s better for all parties to have the full code available to test and comment on. ...

How to use argument in a cast with Delphi

How to do this in Delphi: procedure ToggleVisibility(ControlClass : TControlClass); var i : integer; begin for i := 0 to ComponentCount - 1 do if Components[i] is ControlClass then ...

Complicated C cast explanation

I m trying to figure out what the following code in C does? ((void(*)())buf)(); where buf is a char array.

Beginner: Extending a class in C#, am I doing it wrong?

Again disclaimer disclaimer still learning C# and OOP generally so I hope you ll be patient with me :) I am currently working with a CMS that has a class called FileVersion which basically contains a ...

Casting generic object array to two types

I ve got a method that receives an Object[] and then performs actions on that array. At first I was passing in this array as an IEnumerable<T> however the T can be of two different types. The ...

热门标签