【问题标题】:"cannot return value referencing local variable" when returning PhysicalDevice (Vulkano)返回 PhysicalDevice (Vulkano) 时“无法返回引用局部变量的值”
【发布时间】:2021-06-14 20:18:58
【问题描述】:

我知道这是一个 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,
        // ...
    }
}

我该如何解决这个问题?

【问题讨论】:

    标签: rust ownership


    【解决方案1】:

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

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

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

    其次,假设您重写并删除了 InstanceInfo 结构,而您只想返回 PhysicalDevice&lt;'static&gt;。好吧,如果这是您对编译器的承诺,那么您必须确保您创建的 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();
    }
    

    可能在这里或那里弄错了&amp;,但这就是它的要点。

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

    【讨论】:

    • 谢谢!我仍然需要该结构,因为我还有其他字段,但后一种解决方案有效。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-06-09
    • 1970-01-01
    • 1970-01-01
    • 2016-01-19
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多