我怎样才能让 impl Trait 使用适当的生命周期来对具有另一个生命周期的值进行可变引用?

Alp*_*der 9 lifetime rust

我有一个终生的结构:

struct HasLifetime<'a>( /* ... */ );
Run Code Online (Sandbox Code Playgroud)

有一个 trait 的实现Foo

impl<'a, 'b: 'a> Foo for &'a mut HasLifetime<'b> { }
Run Code Online (Sandbox Code Playgroud)

我想实现以下功能:

fn bar_to_foo<'a, 'b: 'a>(bar: &'a mut Lifetime<'b>) -> impl Foo {
    bar
}
Run Code Online (Sandbox Code Playgroud)

这不会编译,因为返回impl的仅对'a. 但是,指定impl Foo + 'a导致:

struct HasLifetime<'a>( /* ... */ );
Run Code Online (Sandbox Code Playgroud)

带有装箱 trait 对象的看似等效的函数编译:

fn bar_to_foo<'a, 'b: 'a>(bar: &'a mut Lifetime<'b>) -> Box<Foo + 'a> {
    Box::new(bar)
}
Run Code Online (Sandbox Code Playgroud)

我如何定义bar_to_fooimpl Trait

游乐场链接

She*_*ter 9

您需要指出返回的值是建立在多个生命周期之上的。但是,您不能将多个生命周期边界与 一起使用impl Trait,并且尝试这样做不会产生有用的错误消息

还有一招,你可以使用涉及创建具有寿命参数的虚拟特质:

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
}
Run Code Online (Sandbox Code Playgroud)

值得庆幸的是,这仅在“隐藏”生命周期不变时才会发生,这是因为引用是可变的。