如何将 &T 转换为 &Wrapper(T)?

问题描述 投票:0回答:1

我有这段代码展示了我的问题的简化。

struct Wrapper1(u32);

impl Wrapper1 {
    fn inner(&self) -> &u32 {
        &self.0
    }
}

struct Wrapper2(u32);

struct Wrapper3(Wrapper1);

trait GetInner {
    fn inner(&self) -> &Wrapper2;
}

impl GetInner for Wrapper3 {
    fn inner(&self) -> &Wrapper2 {
        let raw_pointer = self.0.inner() as *const u32 as *const Wrapper2;
        unsafe {  &*raw_pointer }
    }
}

我必须依靠

unsafe
,因为我不能只这样做:

impl GetInner for Wrapper3 {
    fn inner(&self) -> &Wrapper2   
        &Wrapper2(*self.0.inner())
    }
}

声音好听吗?我的团队中有人对一致性提出了担忧。 其他人提到我们必须在包装类型上使用

#[repr(transparent)]
才能使其更安全。

rust wrapper unsafe raw-pointer
1个回答
1
投票

您需要

Wrapper2
成为
#[repr(transparent)]
#[repr(C)]
。不保证
#[repr(Rust)
结构的布局。

但是,如果你这样做了,你就不再需要不安全了 - 你可以使用

bytemuck
:

struct Wrapper1(u32);

impl Wrapper1 {
    fn inner(&self) -> &u32 {
        &self.0
    }
}

#[derive(bytemuck::TransparentWrapper)]
#[repr(transparent)]
struct Wrapper2(u32);

struct Wrapper3(Wrapper1);

trait GetInner {
    fn inner(&self) -> &Wrapper2;
}

impl GetInner for Wrapper3 {
    fn inner(&self) -> &Wrapper2 {
        bytemuck::TransparentWrapper::wrap_ref(self.0.inner())
    }
}
© www.soinside.com 2019 - 2024. All rights reserved.