[英]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
的建议对我来说没有意义,因为'b
是bar()
的参数。 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.