有时,我发现自己使用!Sync类型(例如bumpalo::Bump)作为我想要成为Sync的类型实现的一部分.现在我用unsafe impl Sync来表示外部类型,在&mut self种方法中只涉及内部类型.但是,用下面这样的包装器来封装不安全性是否合理?特别是,Send边界是否正确?

pub struct UnCell<T> {
    value: T
}

unsafe impl<T> Sync for UnCell<T> {}

impl<T> UnCell<T> {
    pub fn new(value: T) -> Self {
        Self { value }
    }
    pub fn into_inner(self) -> T {
        self.value
    }
    pub fn get(&mut self) -> &T {
        &self.value
    }
}
impl<T: Send> UnCell<T> {
    pub fn get_mut(&mut self) -> &mut T {
        &mut self.value
    }
}

推荐答案

不仅是声音,还有一个待定的PR添加类型Exclusive,这将允许您安全地执行此操作!

[core] add Exclusive to sync - #97629.

您甚至不需要Send边界:可变引用的值为Sendits referent should also be,因此,如果您在某个线程上有可变引用,您可以安全地访问该引用.

Rust相关问答推荐

为什么单元类型(空元组)实现了`Extend`trait?

返回的future 不是`发送`

可以为rust构建脚本编写单元测试吗?

如何修复数组中NewType导致的运行时开销

如何获取光标下的像素 colored颜色 ?

当我try 使用 SKI 演算中的S I I实现递归时,为什么 Rust 会失败?

为什么 Rust 创建的 f32 小于 f32::MIN_POSITIVE?

Rust 中的静态引用

可选包装枚举的反序列化

Rust编译器通过哪些规则来确保锁被释放?

如何在 Rust 中按 char 对字符串向量进行排序?

&self 参数在 trait 的功能中是必需的吗?

类型判断模式匹配panic

n 个范围的笛卡尔积

为什么 no_std crate 可以依赖于使用 std 的 crate?

火箭整流罩、tokio-scheduler 和 cron 的生命周期问题

为什么这个闭包没有比 var 长寿?

Rust 内联 asm 中的向量寄存器:不能将 `Simd` 类型的值用于内联汇编

为什么这个 Trait 无效?以及改用什么签名?

在传输不可复制的值时实现就地枚举修改