是否有相当于alloca在Rust中创建可变长度数组?
我正在寻找相当于以下C99代码:
void go(int n) {
int array[n];
// ...
}
Run Code Online (Sandbox Code Playgroud) 已经有一个问题,但与Rust 0.13有关,语法似乎已经改变.从当前文档中我了解到在堆上创建数组将是这样的:
fn main() {
const SIZE: usize = 1024 * 1024;
Box::new([10.0; SIZE]);
}
Run Code Online (Sandbox Code Playgroud)
但是当我运行这个程序时,我收到以下错误:
thread '<main>' has overflowed its stack
Run Code Online (Sandbox Code Playgroud)
我究竟做错了什么?
我尝试使用以下代码:
fn main() {
let array = box [1, 2, 3];
}
Run Code Online (Sandbox Code Playgroud)
,在我的程序中,它会导致编译错误:error: obsolete syntax: ~[T] is no longer a type。
AFAIU,Rust 中没有动态大小的数组(大小必须在编译时知道)。然而,在我的代码片段中,数组确实具有静态大小,并且应该是类型~[T, ..3](拥有大小为 3 的静态数组),而编译器说它具有类型~[T]。是否有任何深层原因导致无法在堆上分配静态大小的数组?
PS 是的,我听说过Vec。
在C++中,我可以将1000个数组int放到堆上,如下所示:
int size = 1000;
int* values = new int[size];
delete[] values;
Run Code Online (Sandbox Code Playgroud)
我无法弄清楚如何在Rust中执行等效操作.
let size = 1000;
let values = Box::new([0; size]) // error: non-constant path in constant expression
Run Code Online (Sandbox Code Playgroud)
根据我的理解,Rust强制在编译时知道所有数组的大小,并且在创建数组时不允许使用表达式.
Stack Overflow上已经有几个[i32]关于在堆上分配数组(比如说)的问题.一般建议是拳击,例如Box<[i32]>.但是虽然拳击对于较小的阵列工作得很好,但问题是被装箱的阵列必须首先在堆栈上分配.
因此,如果数组太大(比如1000万个元素),你会 - 甚至用拳击 - 得到一个堆栈溢出(一个不太可能有一个大的堆栈).
然后建议使用Vec<T>,这是Vec<i32>在我们的例子中.虽然这确实起到了作用,但确实会对性能产生影响.
考虑以下程序:
fn main() {
const LENGTH: usize = 10_000;
let mut a: [i32; LENGTH] = [0; LENGTH];
for j in 0..LENGTH {
for i in 0..LENGTH {
a[i] = j as i32;
}
}
}
Run Code Online (Sandbox Code Playgroud)
time告诉我这个程序运行大约需要2.9秒.我在这个例子中使用10'000,所以我可以在堆栈上分配它,但我真的想要一个1000万.
现在考虑相同的程序,但Vec<T>改为:
fn main() {
const LENGTH: usize = 10_000;
let mut a: Vec<i32> = vec![0; LENGTH];
for j in 0..LENGTH {
for i in 0..LENGTH …Run Code Online (Sandbox Code Playgroud) 我正在通过编写简单的二进制解码器来学习 Rust。
我正在使用BufferedReader带有byteorder crate 的 a来读取数字,但是我在读取字节缓冲区时遇到了问题。
我想将字节数据读入在运行时分配的缓冲区中。然后我想将此缓冲区的所有权传递给一个结构。当 struct 不再使用时,应释放缓冲区。
除了一些Vec::with_capacity()hacks之外,似乎没有办法在堆上分配运行时确定的大小的数组。任何想法如何使用适当的 Rust 语义来实现它?