Trait core::ops::DispatchFromDyn

source ·
pub trait DispatchFromDyn<T> { }
🔬This is a nightly-only experimental API. (dispatch_from_dyn)
Expand description

DispatchFromDyn 用于对象安全检查的实现 (特别允许任意 self 类型),以保证可以调度方法的接收者类型。

Note: DispatchFromDyn 被简称为 CoerceSized (并有略微不同的解释)。

想象一下,我们有一个类型为 &dyn Tr 的 trait 对象 t,其中 Tr 是一些 trait,其方法 m 定义为 fn m(&self);。当调用 t.m() 时,接收者 t 是一个宽指针,但 m 的实现将期望一个 narrow 指针为 &self (对具体类型的引用)。 编译器必须生成从 trait object 或 wide 指针到具体 reference 或 narrow 指针的隐式转换。 实现 DispatchFromDyn 表示允许这种转换,因此实现 DispatchFromDyn 的类型可以安全地用作对象安全方法中的 self 类型。 (在上面的例子中,编译器将要求为 &'a U 实现 DispatchFromDyn)。

DispatchFromDyn 没有指定从 wide 指针到 narrow 指针的转换; 转换被硬连接到编译器中。 为使转换工作,以下属性必须保持 (即,只有对具有这些属性的类型实现 DispatchFromDyn 才是安全的,编译器也会检查这些属性) :

  • SelfT 要么都是引用,要么都是裸指针; 无论是哪种情况,都具有相同的可变性。
  • 或者,以下所有条件都成立
    • SelfT 必须具有相同的类型构造函数,仅在单个类型参数形式上有所不同 (*coerced 类型 *,例如 impl DispatchFromDyn<Rc<T>> for Rc<U> 可以,单个类型参数 (用 TU 实例化) 是强制类型,impl DispatchFromDyn<Arc<T>> for Rc<U> 不是行)。

    • Self 的定义必须是结构体。

    • Self 的定义不能是 #[repr(packed)]#[repr(C)]

    • 除了一对齐的零大小字段,Self 的定义必须只有一个字段,并且该字段的类型必须是强制类型。此外,Self 的字段类型必须实现 DispatchFromDyn<F>,其中 FT 的字段类型的类型。

trait 的一个示例实现:

impl<T: ?Sized, U: ?Sized> DispatchFromDyn<Rc<U>> for Rc<T>
where
    T: Unsize<U>,
{}
Run

Implementors§