gpt4 book ai didi

generics - 如何安全地存储通用值的不可变别名副本?

转载 作者:行者123 更新时间:2023-11-29 07:48:16 25 4
gpt4 key购买 nike

总结

出于优化目的,我希望创建一个数据结构,将单个值存储在多个不同的位置。数据结构只会让这些值通过不可变引用使用,或者将它们从数据结构中完全删除。

我如何确保这对于泛型类型是安全的?

简化示例

为上下文提供一个简单(但有些不切实际)的示例,考虑一个缓存最近使用值的切片:

struct Pair<'a> {
values: &'a [T],
last_accessed: &'a T,
}

然而,访问最后访问的元素仍然会导致指针取消引用,因此代码需要按值缓存:

struct Pair<'a> {
values: &'a [T],
last_accessed: NoDrop<T>,
}

在大多数情况下,这似乎是安全的。例如,如果 Tu32 ,缓存只是数据的简单副本。

即使TVec<U> , 这似乎是安全的,因为通过 &last_accessed 进行的任何访问都是安全的不能更改向量的任何直接成员。堆分配是传递不可变且不重复的,因此不存在明显的别名问题。

为什么这么难?

这对所有 值都是不安全的。包含 Cell 的值可能会调用内部可变性并最终违反内部约束,当通过未传播该更改的值访问时会导致不安全行为。

问题是我可以对通用 T 施加什么约束那会让这安全吗?据我所知,我所需要的只是它不包含 UnsafeCell除了通过指针。

T: Copy呢? ?

T: Copy看起来是一个不错的解决方案,但有两个主要缺点:

  • “[ UnsafeCell ] 没有实现 Copy 没有绝对根本的原因” - Alex Crichton . Copy要求似乎是巧合而不是保证。

  • Copy禁止太多; Vec不是 Copy但不需要被禁止。

T: Sync呢?

Sync接近正确的想法,因为

Types that are not Sync are those that have "interior mutability" in a non-thread-safe way, such as Cell and RefCell in std::cell.

但是,一些类型(例如原子)具有线程安全的内部可变性。

最佳答案

您可以使用 auto traitUnsafeCell 实现约束。这些是默认定义的,但可以使用特定类型的特殊语法选择退出 - 您只想为 UnsafeCell 选择退出。

这些以前称为选择加入内置特征 (OIBIT),但已重命名,因为它们既不是选择加入也不一定是内置的,实际上是可以在普通用户代码中定义的选择退出特征.

首先启用它,创建特征并使其默认实现。这使用了一些神奇的语法。

#![feature(optin_builtin_traits)]

pub unsafe trait CopyRef {}
unsafe impl CopyRef for .. {}

然后您选择退出 UnsafeCell

// Opt out of interior mutability
impl<T: ?Sized> !CopyRef for UnsafeCell<T> {}

然后您将需要在指针和 PhantomData 后面重新启用 UnsafeCell

use std::marker::PhantomData;
use std::cell::UnsafeCell;

// Opt in for indirect interior mutability
unsafe impl<'a, T: ?Sized> CopyRef for *const T {}
unsafe impl<'a, T: ?Sized> CopyRef for *mut T {}
unsafe impl<'a, T: ?Sized> CopyRef for &'a T {}
unsafe impl<'a, T: ?Sized> CopyRef for &'a mut T {}

// Box is special and needs its own opt-in
unsafe impl<T: ?Sized> CopyRef for Box<T> {}

// And fake interior mutability
unsafe impl<T: ?Sized> CopyRef for PhantomData<T> {}

瞧。您自己的用户定义的选择退出选择内置自动特征。

关于generics - 如何安全地存储通用值的不可变别名副本?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39756866/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com