我想创建这样的数组:
let arr = [0; length];
当长度为usize
类型时。但是我收到了这个错误。
E0307
The length of an array is part of its type. For this reason, this length
must be a compile-time constant.
是否可以创建动态长度的数组?我想要一个数组,而不是一个Vec
。
能否创建一个动态长度的数组?不行。根据定义,数组的长度在编译时被定义。变量(因为它们可以变化)在编译时是未知的。编译器不会知道要分配多少空间在堆栈上为数组提供存储。
您需要使用Vec
:
let arr = vec![0; length];
另见:
在实现可变长数组(VLA)之后,这应该是可能的。
HeapArray
。如果你阅读alloc
的文档,这并不是很复杂。use std::alloc::{alloc, dealloc, Layout};
pub struct HeapArray<T> {
ptr: *mut T,
len: usize,
}
impl<T> HeapArray<T> {
pub fn new(len: usize) -> Self {
let ptr = unsafe {
let layout = Layout::from_size_align_unchecked(len, std::mem::size_of::<T>());
alloc(layout) as *mut T
};
Self { ptr, len }
}
pub fn get(&self, idx: usize) -> Option<&T> {
if idx < self.len {
unsafe { Some(&*(self.ptr.add(idx))) }
} else {
None
}
}
pub fn get_mut(&self, idx: usize) -> Option<&mut T> {
if idx < self.len {
unsafe { Some(&mut *(self.ptr.add(idx))) }
} else {
None
}
}
pub fn len(&self) -> usize {
self.len
}
}
impl<T> Drop for HeapArray<T> {
fn drop(&mut self) {
unsafe {
dealloc(
self.ptr as *mut u8,
Layout::from_size_align_unchecked(self.len, std::mem::size_of::<T>()),
)
};
}
}
impl<T> std::ops::Index<usize> for HeapArray<T> {
type Output = T;
fn index(&self, index: usize) -> &Self::Output {
self.get(index).unwrap()
}
}
impl<T> std::ops::IndexMut<usize> for HeapArray<T> {
fn index_mut(&mut self, index: usize) -> &mut Self::Output {
self.get_mut(index).unwrap()
}
}
as_slice
,get_unchecked
等方法。from_size_align_unchecked
的 size
参数是以字节为单位的。因此,您必须将 self.len
乘以 std::mem::size_of::<T>()
来计算总大小。 - Majid AzimiVec
有何不同?它像 Vec
一样进行堆分配。 - Neil Mayhewlet ha = HeapArray::<String>::new(10); println!("{}", ha[7]);
这段代码会导致段错误。正常情况下也会导致内存泄漏。编写有缺陷的代码并不是很复杂。 - Shepmaster
Vec
的特性是不如数组的。 - Brian CainSlice
,它类似于Array
,但是Slice
的大小不需要在编译时知道。 - Akavall&[u32]
)吗?如果实际上是切片,那么Vec<T>
可以自由转换为&[T]
,通常只需使用&
:let v: Vec<u32> = ...; let s: &[u32] = &v
。如果他们确实接受对数组的引用,那么动态大小的数组如何帮助您?在这种情况下,Rust没有类型级整数,因此数组的大小必须是恒定的。 - Vladimir Matveev