例如:

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(或者它的某个变种有明确的寿命)是否意味着生锈?如果是,它的使用示例是什么?

最佳答案

自从这个问题被提出以来,锈迹已经改变了很多。虽然该语法目前仍受*支持,但trait对象现在应该用关键字dyn指定:

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

这完全等同于问题中的代码,但更明显的是它的含义:为trait对象实现TraitX
例如:
struct Thing;
impl TraitY for Thing {}

fn main() {
    // Treat the &Thing as a dynamic object
    let object: &dyn TraitY = &Thing;

    // The TraitY object can still be used where a TraitX is expected
    do_something(object);
}

fn do_something<T: TraitX + ?Sized>(t: &T) {
}

表面上,正如你所说,它似乎类似于:
impl<A: TraitY> TraitX for A { }

这为实现dyn TraitY的任何具体类型实现TraitX,但不包括trait对象,因为TraitY始终是类型参数的隐式绑定。但是,我们可以通过显式地选择不使用Sized绑定来消除这一限制:
impl<A: TraitY + ?Sized> TraitX for A { }

这包括实现Sized的所有具体类型,但现在还包括动态TraitY对象。为了达到最大的灵活性,你应该使用这个表格,而不是上面的任何一个选项。
*“当前”是因为未来版本的Rust在这些情况下可能需要关键字。至少,the default linter will disallow omitting it

08-16 02:11