如何为“静态”借用变量?
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());
}
就是说,真的要好好想想我带领的 真的。确保您了解您调用的代码为什么需要 '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
);
在 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());
}
就是说,真的要好好想想我带领的 真的。确保您了解您调用的代码为什么需要 '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
);