简体   繁体   English

使参数通用时出现生命周期错误

[英]Lifetime error when making parameter generic

I've reduced my problem to the following code:我已将我的问题简化为以下代码:

struct Struct<'a, 'b, T> {
    a: &'a T,
    b: &'b T,
}

trait Trait<'a, 'b, T> {
    fn a(&self) -> &'a T;
    fn b(&self) -> &'b T;
}

impl<'a, 'b, T> Trait<'a, 'b, T> for Struct<'a, 'b, T> {
    fn a(&self) -> &'a T {
        self.a
    }
    fn b(&self) -> &'b T {
        self.b
    }
}

struct Confused<T> {
    field: T,
}

impl<T> Confused<T> {
    fn foo<'a, 'b>(&'a self, param: &Struct<'a, 'b, T>) -> &'a T {
        param.b();
        param.a()
    }

    fn bar<'a, 'b, U: Trait<'a, 'b, T>>(&'a self, param: &U) -> &'a T {
        param.b();
        param.a()
    }
}

The function foo is okay, but when I replace the concrete type Struct<'a, 'b, T> with a generic type U: Trait<'a, 'b, T> , I get the following error:函数foo没问题,但是当我用通用类型U: Trait<'a, 'b, T>替换具体类型Struct<'a, 'b, T>U: Trait<'a, 'b, T> ,我收到以下错误:

 error[E0309]: the parameter type `T` may not live long enough --> src/lib.rs:31:15 | 24 | impl<T> Confused<T> { | - help: consider adding an explicit lifetime bound `T: 'b`... ... 31 | param.b(); | ^ | note: ...so that the reference type `&'b T` does not outlive the data it points at --> src/lib.rs:31:15 | 31 | param.b(); | ^

The suggestion to add the bound T: 'b doesn't make sense to me, since 'b is a parameter to bar() .添加绑定T: 'b的建议对我来说没有意义,因为'bbar()的参数。 How can I fix bar() to accept any implementation of Trait<'a, 'b, T> as a parameter?如何修复bar()以接受Trait<'a, 'b, T>任何实现作为参数?

When you write a generic type such as:当您编写泛型类型时,例如:

struct Foo<'a, T> {
    a: &'a T,
}

Rust automatically adds an implicit restriction of the type T: 'a , because your reference to T cannot live longer than T itself. Rust 会自动添加T: 'a类型的隐式限制,因为您对T的引用不能比T本身活得更长。 This is automatic because your type would not work without it.这是自动的,因为没有它,您的类型将无法工作。

But when you do something like:但是,当您执行以下操作时:

impl<T> Foo {
    fn bar<'a, 'b>() -> &'a T {/*...*/}
}

there is an automatic T: 'a but not a T: 'b because there is no &'b T anywhere.有一个自动T: 'a但不是T: 'b因为在任何地方都没有&'b T

The solution is to add those constraints by yourself.解决方案是自己添加这些约束。 In your code it would be something like this:在您的代码中,它将是这样的:

impl<T> Confused<T> {
    fn bar<'a, 'b, U: Trait<'a, 'b, T>>(&'a self, param: &U) -> &'a T
    where
        T: 'b, //<--- here!
    {
        param.b();
        param.a()
    }
}

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

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