简体   繁体   English

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

[英]The trait `A` is not implemented for the type `&'a A + 'a`

I'm having trouble using a generic function that takes a generic trait object as a parameter. 我在使用将通用特征对象作为参数的通用函数时遇到麻烦。 When I try to call the function, the compiler complains “error: the trait Next is not implemented for the type &'a mut Next<Type=Type> + 'a [E0277]”. 当我尝试调用该函数时,编译器会抱怨“错误:类型&'a mut Next<Type=Type> + 'a [E0277]类型未实现特征Next ”。 In my opinion, the Next trait is object-safe for any parameter Type , so Next should be implemented by any &Next<Type> (by my reading of Huon's Object-Safety article ); 在我看来, Next特质对于任何参数Type都是对象安全的,因此Next应该由任何&Next<Type> (根据我对Huon的Object-Safety文章的阅读 ); is there any way to check that it is object-safe? 有什么方法可以检查它是否是对象安全的?

Incidentally, I'm having no problem doing pretty much the same thing with an Iterator , and I don't know how that is different. 顺便说一句,使用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());
}

I think you are adding an extra layer of indirection. 我认为您正在添加额外的间接层。 The method call self.delegate.next() desugars into Next::next(self.delegate) in this case - no automatic referencing (mutable or otherwise) is needed. 在这种情况下,将调用self.delegate.next()的方法分解为Next::next(self.delegate) -不需要自动引用(可变或其他方式)。

The error message is confusing because you have two levels of reference. 该错误消息令人困惑,因为您有两个引用级别。 Your trait is written: 你的特征写成:

trait Next {
    fn next(&mut self)
}

Which means that you always have to pass in a &mut Foo . 这意味着您总是必须传递&mut Foo However, you were taking a second mutable reference, making the argument type &mut &mut NextImpl<Type> . 但是,您正在使用第二个可变引用,其参数类型为&mut &mut NextImpl<Type> The first &mut is matched by the function parameter, but then the rest of the type needs to implement Next . 第一个&mut由函数参数匹配,但是其余的类型需要实现Next However, &mut NextImpl<Type> does not implement that trait, only NextImpl<Type> does! 但是, &mut NextImpl<Type>不会实现该特征,只有NextImpl<Type>可以实现!

Your Sized problem is very similar. 您的Sized问题非常相似。 The function is defined as 该函数定义为

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

That is, it expects a mutable reference to some concrete type that implements Iterator . 也就是说,它期望对实现Iterator 某些具体类型的可变引用。 Your call passes a &mut Iterator - a trait object . 您的呼叫传递了&mut Iterator - trait对象 A trait object is a reference to something without a known size, it is only known to implement the methods of the trait. 特征对象是对没有已知大小的东西的引用,只有实现特征的方法才知道。 Since you don't care about the size of the thing being referred to, the correct option is to declare that, as you did: 由于您不在乎所引用对象的大小,因此正确的选择是像声明的那样声明:

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

This is super confusing, so let me know if I need to attempt to explain it differently. 这非常令人困惑,所以让我知道是否需要尝试以不同的方式解释它。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM