我正在try 制作类似于不可变字典特性的东西,可以在不影响以前版本的情况下添加新项目(引用)并使用它.最小示例:

#[derive(Clone)]
pub struct SetOfValues<'a> {
    value: Vec<&'a i32>,
}

pub trait TheSetAccessor<'b> {
    fn with_additional_values(&self, new_set: Vec<&'b i32>) -> Box<dyn TheSetAccessor<'b>>;
    fn get_from_set(&self, index: usize) -> &i32;
}

impl<'a, 'b : 'a> TheSetAccessor<'b> for SetOfValues<'a> {
    fn with_additional_values(&self, new_set: Vec<&'b i32>) -> Box<dyn TheSetAccessor<'b>> {
        Box::new(SetOfValues { value: new_set } )
    }

    fn get_from_set(&self, index: usize) -> &i32 {
        self.value[index]
    }
}

fn usage() {
    let a = 0;
    let set = SetOfValues {
        value: vec![&a]
    };

    // ...

    let b = 1;
    let extended_set = set.with_additional_values(vec![&a, &b]);

    // ...

    let got_b = extended_set.get_from_set(1);
}

错误消息如下:

error[E0495]: cannot infer an appropriate lifetime for lifetime parameter `'a` due to conflicting requirements
  --> src/test.rs:13:18
   |
13 |         Box::new(SetOfValues { value: new_set } )
   |                  ^^^^^^^^^^^
   |
note: first, the lifetime cannot outlive the lifetime `'b` as defined here...
  --> src/test.rs:11:10
   |
11 | impl<'a, 'b : 'a> TheSetAccessor<'b> for SetOfValues<'a> {
   |          ^^
note: ...so that the expression is assignable
  --> src/test.rs:13:39
   |
13 |         Box::new(SetOfValues { value: new_set } )
   |                                       ^^^^^^^
   = note: expected `Vec<&i32>`
              found `Vec<&'b i32>`
   = note: but, the lifetime must be valid for the static lifetime...
note: ...so that the types are compatible
  --> src/test.rs:13:9
   |
13 |         Box::new(SetOfValues { value: new_set } )
   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
   = note: expected `Box<(dyn TheSetAccessor<'b> + 'static)>`
              found `Box<dyn TheSetAccessor<'b>>`

据我所知,新的值集应该具有传递向量('b)的生存期,但这部分

首先,生命周期 不能超过此处定义的生命周期 'b...

如我所见,这表明SetOfValues的新实例有另一个生存期("静态的")那应该比b活得更长.我不太明白我怎么能限制这一生.我该怎么做才能使此代码正常工作?

推荐答案

这是因为dyn Trait实际上是dyn Trait + 'static.因此,dyn TheSetAccessor<'b>实际上是dyn TheSetAccessor<'b> + 'static,并且不能包含任何非'static生存期,因此它需要'b: 'static.

要放松这一限制,在trait 上加上一个生命周期:dyn TheSetAccessor<'b> + 'b.注意,这可能不是最好的解决方案,具体取决于您的用例.

fn with_additional_values(&self, new_set: Vec<&'b i32>) -> Box<dyn TheSetAccessor<'b> + 'b>;

Playground.

Rust相关问答推荐

阻止websocket中断的中断中断的终端(操作系统错误4)

如果A == B,则将Rc A下推到Rc B

我如何在Rust中使用传递依赖中的特征?

值为可变对象的不可变HashMap

这是不是在不造成嵌套的情况下从枚举中取出想要的变体的惯用方法?

在rust sqlx中使用ilike和push bind

如何使用Actix Web for Rust高效地为大文件服务

如何设置activx websocket actorless的消息大小限制?

为什么 GAT、生命周期和异步的这种组合需要 `T: 'static`?

std mpsc 发送者通道在闭包中使用时关闭

`use` 和 `crate` 关键字在 Rust 项目中效果不佳

为什么 Rust 字符串没有短字符串优化 (SSO)?

如何在 Rust 中显式声明 std::str::Matches<'a, P> ?

有什么办法可以追踪泛型的单态化过程吗?

如何在 Rust 中将 Vec> 转换为 Vec>?

从嵌入式 Rust 中的某个时刻开始经过的时间

使用自定义 struct 收集 Vec

预期的整数,找到 `&{integer}`

如何从 Rust 应用程序连接到 Docker 容器中的 SurrealDB?

来自外部函数的future 内部可变引用