锈:借入的值必须在静态生命周期内有效

stu*_*ffy 4 rust

我正在Rust的一个玩具射线追踪器项目中工作,并且挂了一个与生命有关的错误。我将代码简化为以下独立的失败案例:

struct Material {}

pub struct Sphere<'a> {
    material: &'a Material,
}

pub trait AnySceneObject {}

impl<'a> AnySceneObject for Sphere<'a> {}

pub struct Scene {
    objects: Vec<Box<AnySceneObject>>,
}

fn main() {
    let material = Material {};
    let boxed_sphere: Box<AnySceneObject> = Box::new(Sphere { material: &material });
    Scene { objects: vec![boxed_sphere] };
}
Run Code Online (Sandbox Code Playgroud)

哪个抱怨

error[E0597]: `material` does not live long enough
  --> main.rs:17:74
   |
17 |     let boxed_sphere: Box<AnySceneObject> = Box::new(Sphere { material: &material });
   |                                                                          ^^^^^^^^ does not live long enough
18 |     Scene { objects: vec![boxed_sphere] };
19 | }
   | - borrowed value only lives until here
   |
  = note: borrowed value must be valid for the static lifetime...

error: aborting due to previous error(s)
Run Code Online (Sandbox Code Playgroud)

我想使用特征在场景中定义对象,但是我希望Scene对象拥有它们。我目前的理解是,这意味着我需要Box或等同的东西,因为特征对象的大小未知。

我还希望对象共享对Materials的引用,因为不会有太多对象,尽管它们相对简单且Copy能够,但我不希望从字面上看成千上万的同一事物的相同副本(因此使用&'a Material)。

我很困惑为什么它是有问题的传递&material虽然这里:因为值之后最新一,不会Scene首先被丢弃,从而boxed_sphere被丢弃(因为它现在拥有一个Vec拥有该Box),它然后,允许material以掉线,没问题吗?好像它应该至少与该函数中的其他两个值一样长,因为我要保留带有material整个函数范围名称的值。

同样令人困惑的是,Scene出于我不理解的原因,注释掉了修复实例的实例。

Pav*_*hov 5

首先,如果您有成千上万个场景对象,将它们放在盒子中(基本上是一个堆对象)绝对不是一个好主意。

调用该错误是因为Box的内容不得包含任何可能过期的引用。您可以四处Box走动,直到过程结束,它才可能被删除,因此它保存的所有引用都必须具有'static生命周期。

您可以通过使用Box<T + 'a>来指示它将有有限的寿命来对其进行修复:

pub struct Scene<'a> {
    objects: Vec<Box<AnySceneObject + 'a>>,
}
Run Code Online (Sandbox Code Playgroud)

您还可以Vec<&Trait>用来存储对实现特征的不同对象的引用的集合。以下代码编译:

pub struct Scene<'a> {
    objects: Vec<&'a AnySceneObject>,
}

fn main() {
    let material = Material {};
    let sphere = Sphere { material: &material };
    Scene {
        objects: vec![&sphere] 
    };
}
Run Code Online (Sandbox Code Playgroud)

如果您知道特征的所有可能实现,则可以将其替换为枚举。这将使代码更具性能,因为您将拥有拥有枚举而不是引用的向量。


归档时间:

查看次数:

2189 次

最近记录:

8 年,2 月 前