gpt4 book ai didi

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

转载 作者:行者123 更新时间:2023-11-29 08:12:10 32 4
gpt4 key购买 nike

我知道 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() {}

在上面的代码中,good() 没有报错,但是 bad() 报错:

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>

这段代码中没有Box,不知道静态生命周期从何而来。

编辑:通过反复尝试,我发现编译器假设 Stack + 'static。下面的代码编译。但为什么?请指出一些文件。

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) 实现特征 (Stack<T>)。

Rust reference 状态:

Since a trait object can contain references, the lifetimes of those references need to be expressed as part of the trait object. This lifetime is written as Trait + 'a. There are defaults that allow this lifetime to usually be inferred with a sensible choice.

如果您没有定义生命周期,编译器会假定一个默认值,在本例中,假定为 '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() 方法返回一个生命周期为 'static 的特征对象。

trait 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() 可以,而在 index() 中使用 bad() 却不行?

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

use std::ops::Index;

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

// equivalent to: impl<T> Index<usize> for Stack<T>
// just to expose the conflicting requirements error
// the right declaration is:
// impl<'a, T> Index<usize> for Stack<T> + 'a
impl<T> Index<usize> for Stack<T> + 'static {
type Output = T;
fn index(&self, i: usize) -> &T {
&self.as_slice()[i]
}
}

trait Core {
fn stack(&self) -> &Stack<usize>;
fn bad<'a>(&'a mut self) -> usize {
//self.stack()[0] syntactic sugar for:
*self.stack().index(0)

// self.stack() returns a trait object with a lifetime bound != 'static
// but Stack impl for Index requires a 'static lifetime bound:
// COMPILE ERROR: cannot infer an appropriate lifetime for
// autoref due to conflicting requirements
}
fn good<'a>(&'a mut self) -> usize {
// self.stack() returns a trait object with 'a lifetime bound
// this is congruent with as_slice() lifetime requirements
// see Catasta::as_slice() impl below
// NO COMPILE ERROR
self.stack().as_slice()[0]
}
}

struct Catasta<T> {
pila: [T;4]
}

impl<T> Stack<T> for Catasta<T> {

fn as_slice<'a>(&'a self) -> &'a [T] {
&self.pila
}
}

struct RealCore {
stk: Catasta<usize>
}

impl Core for RealCore {
fn stack(&self) -> &Stack<usize> {
&self.stk
}
}

fn main() {
let mut core = RealCore {stk: Catasta {pila: [100, 2, 3, 4]} };
println!("pos [0] item: {}", core.good());
}

关于rust - 生命周期必须对静态生命周期有效,以便类型兼容,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52187644/

32 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com