我怎样才能让 impl Trait 使用适当的生命周期来可变引用另一个生命周期的值?
How can I get impl Trait to use the appropriate lifetime for a mutable reference to a value with another lifetime in it?
我有一个有生命周期的结构:
struct HasLifetime<'a>( /* ... */ );
有一个特性的实现 Foo
:
impl<'a, 'b: 'a> Foo for &'a mut HasLifetime<'b> { }
我要实现以下功能:
fn bar_to_foo<'a, 'b: 'a>(bar: &'a mut Lifetime<'b>) -> impl Foo {
bar
}
这不会编译,因为返回的 impl
仅对 'a
有效。但是,指定 impl Foo + 'a
会导致:
error[E0909]: hidden type for `impl Trait` captures lifetime that does not appear in bounds
--> src/main.rs:7:60
|
7 | fn bar_to_foo<'a, 'b: 'a>(bar: &'a mut HasLifetime<'b>) -> impl Trait + 'a {
| ^^^^^^^^^^^^^^^
|
note: hidden type `&'a mut HasLifetime<'b>` captures the lifetime 'b as defined on the function body at 7:1
--> src/main.rs:7:1
|
7 | fn bar_to_foo<'a, 'b: 'a>(bar: &'a mut HasLifetime<'b>) -> impl Trait + 'a {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
带有盒装特征对象的看似等效的函数编译:
fn bar_to_foo<'a, 'b: 'a>(bar: &'a mut Lifetime<'b>) -> Box<Foo + 'a> {
Box::new(bar)
}
如何用 impl Trait
定义 bar_to_foo
?
您需要指明返回值是建立在多个生命周期之上的。但是,您不能对 impl Trait
使用多个生命周期边界,并试图这样做 doesn't have a useful error message.
a trick you can use 涉及创建具有生命周期参数的虚拟特征:
trait Captures<'a> {}
impl<'a, T: ?Sized> Captures<'a> for T {}
fn bar_to_foo<'a, 'b: 'a>(bar: &'a mut HasLifetime<'b>) -> impl Trait + Captures<'b> + 'a {
bar
}
谢天谢地,这个 only occurs when the "hidden" lifetime is invariant,这是因为引用是可变的。
我有一个有生命周期的结构:
struct HasLifetime<'a>( /* ... */ );
有一个特性的实现 Foo
:
impl<'a, 'b: 'a> Foo for &'a mut HasLifetime<'b> { }
我要实现以下功能:
fn bar_to_foo<'a, 'b: 'a>(bar: &'a mut Lifetime<'b>) -> impl Foo {
bar
}
这不会编译,因为返回的 impl
仅对 'a
有效。但是,指定 impl Foo + 'a
会导致:
error[E0909]: hidden type for `impl Trait` captures lifetime that does not appear in bounds
--> src/main.rs:7:60
|
7 | fn bar_to_foo<'a, 'b: 'a>(bar: &'a mut HasLifetime<'b>) -> impl Trait + 'a {
| ^^^^^^^^^^^^^^^
|
note: hidden type `&'a mut HasLifetime<'b>` captures the lifetime 'b as defined on the function body at 7:1
--> src/main.rs:7:1
|
7 | fn bar_to_foo<'a, 'b: 'a>(bar: &'a mut HasLifetime<'b>) -> impl Trait + 'a {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
带有盒装特征对象的看似等效的函数编译:
fn bar_to_foo<'a, 'b: 'a>(bar: &'a mut Lifetime<'b>) -> Box<Foo + 'a> {
Box::new(bar)
}
如何用 impl Trait
定义 bar_to_foo
?
您需要指明返回值是建立在多个生命周期之上的。但是,您不能对 impl Trait
使用多个生命周期边界,并试图这样做 doesn't have a useful error message.
a trick you can use 涉及创建具有生命周期参数的虚拟特征:
trait Captures<'a> {}
impl<'a, T: ?Sized> Captures<'a> for T {}
fn bar_to_foo<'a, 'b: 'a>(bar: &'a mut HasLifetime<'b>) -> impl Trait + Captures<'b> + 'a {
bar
}
谢天谢地,这个 only occurs when the "hidden" lifetime is invariant,这是因为引用是可变的。