首页 文章

什么“TraitX for TraitY”在Rust中意味着什么?

提问于
浏览
2

例如:

trait TraitX { }
trait TraitY { }
impl TraitX for TraitY { }

我认为这意味着相同

impl<A: TraitY> TraitX for A { }

但错误消息暗示:

$ rustc --version
rustc 0.12.0-nightly (a70a0374e 2014-10-01 21:27:19 +0000)
$ rustc test.rs
test.rs:3:17: 3:23 error: explicit lifetime bound required
test.rs:3 impl TraitX for TraitY { }
                          ^~~~~~

impl TraitX for TraitY (或具有明确生命周期的某些变体)是否表示Rust中的任何内容?如果是这样,它的用途是什么?

1 回答

  • 4

    impl TraitX for TraitY 正在使用 TraitY 作为a dynamically sized type (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 { }
             ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    

    playpen

    错误是说 TraitY+'a 没有大小,也就是说,它在编译时没有已知的大小(例如 u8 的大小为1, Vec<T> 是3个指针的大小) .

    语法正在为 TraitY trait对象实现 TraitX (这些在引用的"object types" section中有所涉及),允许在需要实现 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() {}
    

    playpen

    当前调用具有unsized类型的函数时,需要显式的 ::<TraitY> 类型提示,但这是一个错误#17178 . 目前,还有quite a few bugs with DST所以在实践中实际使用起来并不容易,但这会有所改善 .

    DST的主要动机是使处理特征对象与其他指针类型更加一致,例如:我们目前只支持 &TraitBox<Trait> 特征对象,但DST旨在允许其他指针类型,如 Rc<Trait>Arc<Trait> . DST还允许将那些像真正的指针一样处理,例如如果 obj: Box<Trait> 然后 &*obj 现在只能使用DST,以前它是非法的,因为特征对象是胖指针,而不是普通指针 .

相关问题