impl TraitX for TraitY
TraitY
用作动态大小的类型 (DST)。如果我们添加所需的生命周期限制(有关生命周期限制的必要性的更多信息,请参见例如this),编译器将以这种方式抱怨:
trait TraitX { }
trait TraitY { }
impl<'a> TraitX for TraitY+'a { }
fn main() {}
<anon>:3:1: 3:34 error: the trait `core::kinds::Sized` is not implemented for the type `TraitY+'a`
<anon>:3 impl<'a> TraitX for TraitY+'a { }
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
<anon>:3:1: 3:34 note: the trait `core::kinds::Sized` must be implemented because it is required by `TraitX`
<anon>:3 impl<'a> TraitX for TraitY+'a { }
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
围栏
错误是说TraitY+'a
没有大小,也就是说,它在编译时没有已知的大小(例如u8
,大小为 1,Vec<T>
是 3 个指针的大小)。
该语法是TraitX
为TraitY
特征对象实现的(这些在参考的“对象类型”部分中有介绍),允许在需要实现值的地方处理它(在指针后面)TraitX
。工作用法涉及一些额外的Sized?
注释,这些注释表示它们附加到的任何东西都是可选的 ( ?
) 大小(默认是假定大小的东西)。
#![allow(dead_code)]
// indicate that it's OK to implement this trait for DSTs
trait TraitX for Sized? { }
trait TraitY { }
trait TraitZ { }
impl<'a> TraitX for TraitY+'a { }
// the Sized? is to allow DSTs to be passed to this.
fn example<Sized? T: TraitX>(_: &T) {}
fn call_it(x: &TraitY, _y: &TraitZ) {
example::<TraitY>(x); // only possible if `TraitY` impls `TraitX`.
// error:
// example::<TraitZ>(_y); // `TraitZ` doesn't impl `TraitX`.
}
fn main() {}
围栏
::<TraitY>
现在调用具有未定义类型的函数时需要显式类型提示,但这是一个错误#17178。目前,DST 仍然存在相当多的错误,因此在实践中实际使用并不容易,但这会有所改善。
DST 的主要动机是使处理 trait 对象与其他指针类型更加一致,例如,我们目前仅支持&Trait
和Box<Trait>
trait 对象,但 DST 被设计为允许其他指针类型,如Rc<Trait>
, Arc<Trait>
。DST 还允许将它们视为真正的指针,例如,如果现在只能使用 DST,那么以前它是非法的,因为 trait 对象是胖指针,而不是普通指针obj: Box<Trait>
。&*obj