生命周期必须对静态生命周期有效,以便类型兼容

问题描述 投票:1回答:1

我知道Where did the 'static lifetime come fromCannot infer an appropriate lifetime for autoref due to conflicting requirements

但我仍然不明白我遇到的问题:

use std::ops::Index;

trait Stack<T> {
    fn as_slice(&self) -> &[T];
}

impl<T> Index<usize> for Stack<T> {
    type Output = T;
    fn index(&self, i: usize) -> &T {
        &self.as_slice()[i]
    }
}

trait Core {
    fn stack(&self) -> &Stack<usize>;
    fn bad(&mut self) -> usize {
       self.stack()[0]
    }
    fn good(&mut self) -> usize {
       self.stack().as_slice()[0]
    }
}

fn main() {}

在上面的代码中,qazxsw poi没有错误,但是qazxsw poi抱怨:

good()

这段代码中没有bad(),我不知道静态生命的来源。

编辑:通过尝试和错误我发现编译器假设Stack +'静态。以下代码编译。但为什么?请指点我的文件。

error[E0495]: cannot infer an appropriate lifetime for autoref due to conflicting requirements
--> src/main.rs:18:14
|
18 |         self.stack()[0]
|              ^^^^^
|
note: first, the lifetime cannot outlive the anonymous lifetime #1 defined on the method body at 17:5...
--> src/main.rs:17:5
|
17 | /     fn bad(&mut self) -> usize {
18 | |         self.stack()[0]
19 | |     }
| |_____^
note: ...so that reference does not outlive borrowed content
--> src/main.rs:18:9
|
18 |         self.stack()[0]
|         ^^^^
= note: but, the lifetime must be valid for the static lifetime...
= note: ...so that the types are compatible:
        expected std::ops::Index<usize>
            found std::ops::Index<usize>
rust
1个回答
4
投票

您正在为特征对象(Box)实现特征(impl<'b, T> Index<usize> for Stack<T> + 'b { type Output = T; fn index<'a>(&'a self, i: usize) -> &'a T { &self.as_slice()[i] } } )。

Index说:

由于特征对象可以包含引用,因此这些引用的生命周期需要表示为特征对象的一部分。这个生命周期写成Trait +'a。有一些默认值允许通常在明智的选择下推断这个生命周期。

如果你没有定义一个生命周期,编译器会假设一个默认值,在这种情况下,它假定为Stack<T>(有关详细说明,请参阅Rust reference

您的代码相当于:

'static

要解决here编译错误,只需声明impl<T> Index<usize> for Stack<T> + 'static { type Output = T; fn index(&self, i: usize) -> &T { &self.as_slice()[i] } } 方法返回一个具有cannot infer an appropriate lifetime for autoref due to conflicting requirements生命周期的特征对象。

stack()

否则,为impl 'statictrait Core { fn stack(&self) -> &'static Stack<usize>; fn bad(&mut self) -> usize { self.stack()[0] } fn good(&mut self) -> usize { self.stack().as_slice()[0] } } 特征对象声明一个通用生命周期:

Stack<T>

在这一点上你应该问:为什么在Index中使用impl<'a, T> Index<usize> for Stack<T> + 'a { type Output = T; fn index(&self, i: usize) -> &T { &self.as_slice()[i] } } trait Core { fn stack(&self) -> &Stack<usize>; fn bad(&mut self) -> usize { self.stack()[0] } fn good(&mut self) -> usize { self.stack().as_slice()[0] } } 并在as_slice()中使用good()不?

要理解它,请尝试阅读下面MVCE中嵌入的注释。

index()
© www.soinside.com 2019 - 2024. All rights reserved.