特征“A”没有实现类型“&”A +'a`

时间:2015-05-15 00:37:46

标签: rust

我在使用将通用特征对象作为参数的泛型函数时遇到了麻烦。当我尝试调用该函数时,编译器会抱怨“错误:未对类型Next [E0277]”实现特征&'a mut Next<Type=Type> + 'a。在我看来,Next特征对于任何参数Type都是对象安全的,所以Next应由任何&Next<Type>实现(通过我阅读Huon’s Object-Safety article );有没有办法检查它是否是对象安全的?

顺便说一句,我对使用Iterator做同样的事情没有任何问题,我不知道这有什么不同。

trait Next {
    type Type;
    fn next(&mut self) -> Option<Self::Type>;
}
struct NextImpl<Type> {
    next: Option<Type>,
}
impl<Type> Next for NextImpl<Type> {
    type Type = Type;
    fn next(&mut self) -> Option<Self::Type> {
        let mut ret = None;
        std::mem::swap(&mut self.next, &mut ret);
        ret
    }
}

struct DelegatingNext<'a, Type> {
    delegate: &'a mut Next<Type=Type>,
}
impl<'a, Type> Next for DelegatingNext<'a, Type> {
    type Type = Type;
    fn next(&mut self) -> Option<Self::Type> {
        self.delegate.next()

        // error: the trait `Next` is not implemented for the type `&'a mut Next<Type=Type> + 'a` [E0277]
        // Next::next(&mut self.delegate)
        // ^~~~~~~~~~

        // error: the trait `Next` is not implemented for the type `&'a mut Next<Type=Type> + 'a` [E0277]
        // if (true) {
        // next_next1(&mut self.delegate)
        // ^~~~~~~~~~

        // error: the trait `Next` is not implemented for the type `&'a mut Next<Type=Type> + 'a` [E0277]
        // next_next2(&mut self.delegate)
        //            ^~~~~~~~~~~~~~~~~~
    }
}
fn next_next1<'a, NextType: Next + ?Sized>(m: &'a mut NextType) -> Option<NextType::Type> {
    m.next()
}
fn next_next2<'a, Type>(m: &'a mut Next<Type=Type>) -> Option<Type> {
    m.next()
}
struct DelegatingIterator<'b, T> {
    iter: &'b mut Iterator<Item=T>,
}
impl<'b, T> DelegatingIterator<'b, T> {
    fn next(&mut self) -> Option<T> {
        let iter: &mut Iterator<Item=T> = self.iter;

        iterator_next1(iter)

        // error: the trait `core::marker::Sized` is not implemented for the type `core::iter::Iterator<Item=T>` [E0277]
        // note: `core::iter::Iterator<Item=T>` does not have a constant size known at compile-time
        // iterator_next2(iter)
        // ^~~~~~~~~~~~~~

        // OK
        // iterator_next3(iter)

        // OK
        // iterator_next4(iter)
    }
}
fn iterator_next1<'a, T>(iter: &mut Iterator<Item=T>) -> Option<T> {
    iter.next()
}
fn iterator_next2<It: Iterator>(iter: &mut It) -> Option<It::Item> {
    iter.next()
}
fn iterator_next3<It: Iterator + ?Sized>(iter: &mut It) -> Option<It::Item> {
    iter.next()
}
fn iterator_next4<'a, Item>(iter: &mut Iterator<Item=Item>) -> Option<Item> {
    iter.next()
}

fn main() {
    let mut m = NextImpl {next: Some("hi")};
    let mut delegating_model = DelegatingNext {delegate: &mut m};
    assert!(Some("hi") == delegating_model.next());
    let v: Vec<i32> = vec!(1, 2, 3);
    let mut iter = v.iter();
    assert_eq!(Some(&1), (DelegatingIterator {iter: &mut iter }).next());
}

1 个答案:

答案 0 :(得分:3)

我认为你正在添加一个额外的间接层。在这种情况下,方法调用self.delegate.next() desugars into Next::next(self.delegate) - 不需要自动引用(可变或其他)。

错误消息令人困惑,因为您有两个级别的引用。你的特质是:

trait Next {
    fn next(&mut self)
}

这意味着您必须传递&mut Foo。但是,您正在使用第二个可变引用,使参数类型为&mut &mut NextImpl<Type>。第一个&mut与函数参数匹配,但其余类型需要实现Next。但是,&mut NextImpl<Type>没有实现该特征,只有NextImpl<Type>可以实现!

您的Sized问题非常相似。该函数定义为

fn iterator_next2<It: Iterator>(iter: &mut It) -> Option<It::Item>

也就是说,它期望对某些实现Iterator的具体类型的可变引用。您的来电通过&mut Iterator - 特征对象。特征对象是对没有已知大小的东西的引用,只知道实现特征的方法。既然你不关心被引用的东西的大小,正确的选择就是像你一样声明:

fn iterator_next3<It: Iterator + ?Sized>(iter: &mut It) -> Option<It::Item> {
    iter.next()
}

这非常令人困惑,所以如果我需要尝试以不同的方式解释它,请告诉我。