如何为“静态”借用变量?

How can I make a variable borrow for 'static?

vulkano 中,要创建一个 CPUAccessibleBuffer,您需要为其提供一些数据,而 CPUAccessibleBuffer::from_data 函数要求数据具有 'static 生命周期。

我在 &[u8] 数组(在运行时创建)中有一些数据,我想将其传递给该函数。

但是,此消息出错

argument requires that `data` is borrowed for `'static`

那么我怎样才能使数据的生命周期 'static 呢?

创建一个 static 生命周期的常量:

static NUM: i32 = 18;

如果数据是在运行时创建的,它就不能有静态的生命周期。静态意味着数据在程序的整个生命周期内都存在,这在某些情况下是必需的,尤其是在涉及线程时。数据是静态的一种方法是,正如保罗已经回答的那样,明确声明它,即:

static constant_value: i32 = 0;

但是,没有普遍适用的方法可以使任意数据静态化。这种类型的推断是由借用检查器在编译时进行的,而不是由程序员进行的。

通常,如果一个函数需要 'static(类型)参数(如本例),则意味着任何更少的参数都可能是不安全的,您需要重新组织数据流入和流出程序的方式安全地提供此类数据。不幸的是,这不是 SO 可以在这个问题的范围内提供的东西。

如果您真的必须在运行时创建数据,并且您真的需要持续'static,那么您可以使用一种内存泄漏方法,例如 Box::leak or Vec::leak 故意泄漏堆分配并确保它永远不会被释放。

虽然通常会避免内存泄漏,但在这种情况下,这实际上是一件明智的事情。如果数据必须永远存在,那么从语义上讲,泄漏实际上是正确的做法。您希望释放内存,永远不会,这正是内存泄漏时发生的情况。

示例:

fn require_static_data(data: &'static [u8]) {
    unimplemented!()
}

fn main() {
    let data = vec![1, 2, 3, 4];
    require_static_data(data.leak());
}

Playground

就是说,真的要好好想想我带领的 真的。确保您了解您调用的代码为什么需要 'static 数据,并问问自己为什么您的数据还没有 'static.

  • 是否可以在编译时创建数据? Rust 有一个强大的构建时宏系统。例如,可以使用 include_bytes! 读入文件并在将其嵌入可执行文件之前对其进行一些处理。

  • 是否还有另一个 API 您可以使用,另一个您没有看到的不需要 'static 的函数调用?

(这些问题不是专门针对您的,而是针对以后遇到此问答的任何人的。)

您应该改用 CpuAccessibleBuffer::from_iter,它做同样的事情但不要求集合是 Copy'static:

let data: &[u8] = todo!();

let _ = CpuAccessibleBuffer::from_iter(
    device,
    usage,
    host_cached,
    data.iter().copied(), // <--- pass like so
);

或者如果你真的有一个Vec<u8>,你可以直接传过去:

let data: Vec<u8> = todo!();

let _ = CpuAccessibleBuffer::from_iter(
    device,
    usage,
    host_cached,
    data, // <--- pass like so
);