Trait std::ops::DispatchFromDyn
source · pub trait DispatchFromDyn<T> { }
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
才是安全的,编译器也会检查这些属性) :
Self
和T
要么都是引用,要么都是裸指针; 无论是哪种情况,都具有相同的可变性。- 或者,以下所有条件都成立
-
Self
和T
必须具有相同的类型构造函数,仅在单个类型参数形式上有所不同 (*coerced 类型 *,例如impl DispatchFromDyn<Rc<T>> for Rc<U>
可以,单个类型参数 (用T
或U
实例化) 是强制类型,impl DispatchFromDyn<Arc<T>> for Rc<U>
不是行)。 -
Self
的定义必须是结构体。 -
Self
的定义不能是#[repr(packed)]
或#[repr(C)]
。 -
除了一对齐的零大小字段,
Self
的定义必须只有一个字段,并且该字段的类型必须是强制类型。此外,Self
的字段类型必须实现DispatchFromDyn<F>
,其中F
是T
的字段类型的类型。
-
trait 的一个示例实现:
impl<T: ?Sized, U: ?Sized> DispatchFromDyn<Rc<U>> for Rc<T>
where
T: Unsize<U>,
{}
Run