返回 PhysicalDevice (Vulkano) 时“无法返回引用局部变量的值”

问题描述

我知道这是一个 Rust 新手问题,但我实际上无法解决它。我需要传递来自 Vulkano 库的 PhysicalDevice。问题是,PhysicalDevice 持有一个引用:

pub struct PhysicalDevice<'a> {
    instance: &'a Arc<Instance>,device: usize,}

所以 Rust 不会编译我的神圣代码

struct InstanceInfo<'a> {
    instance: Arc<Instance>,physical: PhysicalDevice<'a>,// ...
}

// ...

fn instantiate() -> InstanceInfo<'static> {
    // ...
    let instance = Instance::new(None,&required_extensions,None).unwrap();
    
    let physical = PhysicalDevice::enumerate(&instance).next().unwrap();
    // ...
    InstanceInfo { // cannot return value referencing local blah
        instance,physical,// ...
    }
}

我该如何解决这个问题?

解决方法

因此错误消息的原因是 instance 是您的 instantiate 函数中的局部变量。因为您没有将其所有权移至返回值,所以它会在函数结束时被删除。

但是如果它被删除,任何对它的引用都将无效。这就是为什么 Rust 不允许你返回包含对局部变量的引用的东西。

首先,您的结构体是多余的,因为 PhysicalDevice 已经拥有实例的引用。即使没有局部变量问题,我认为您也会遇到所有权问题。

其次,假设您重写并删除了 InstanceInfo 结构,而您只想返回一个 PhysicalDevice<'static>。好吧,如果这就是您对编译器的承诺,那么您必须确保您创建的 instance 将与程序存在的时间一样长。

您可以通过让 instance 成为模块的静态变量来实现,或者在程序的最开始创建它,然后简单地传递它的引用。

例如

fn main() {
 let instance = Instance::new(None,blablabla).unwrap();
 
 let physical = instantiate(&instance);
}

fn instantiate<'a>(instance: &'a Arc<Instance>) -> PhysicalDevice<'a> {
  PhysicalDevice::enumerate(instance).next().unwrap();
}

可能在这里或那里犯了一个 & 错误,但这是它的要点。

如果您必须将所有内容放入一个额外的结构体中,那么我认为您想要做的是clone Arc 而不是仅仅移动它。 >