如何动态设置Rust数组长度?

时间:2016-01-08 19:05:03

标签: arrays rust

我想创建这样的数组:

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

3 个答案:

答案 0 :(得分:22)

  

是否可以创建动态长度的数组?

没有。根据定义,数组的长度在编译时定义。变量(因为它可以变化)在编译时是未知的。编译器不知道在堆栈上分配多少空间来为阵列提供存储。

您需要使用Vec

let arr = vec![0; length];

答案 1 :(得分:2)

在实现可变长度数组(VLA)之后,这将是可能的。

https://doc.rust-lang.org/beta/unstable-book/language-features/unsized-locals.html

答案 2 :(得分:1)

您可以创建自己的HeapArray。阅读alloc's docs并没有那么复杂:

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_sliceget_unchecked等方法。