这个问题在这里已经有了答案:





Is there a good way to convert a Vec<T> to an array?

(1 个回答)


6年前关闭。




我试图找出从向量转换为数组并返回的最类似于 Rust 的方式。这些宏可以工作,甚至可以用一些不安全的块来通用,但感觉都非常不像 Rust。

我将不胜感激任何输入并且没有任何冲击,我认为这段代码远非很好或最佳。我现在只玩了几个星期的 Rust 并追逐发布和文档,所以非常感谢帮助。

macro_rules! convert_u8vec_to_array {
    ($container:ident, $size:expr) => {{
    if $container.len() != $size {
            None
    } else {
        use std::mem;
        let mut arr : [_; $size] = unsafe { mem::uninitialized() };
        for element in $container.into_iter().enumerate() {
            let old_val = mem::replace(&mut arr[element.0],element.1);
            unsafe { mem::forget(old_val) };
        }
        Some(arr)
        }
    }};
}

fn array_to_vec(arr: &[u8]) -> Vec<u8> {
     let mut vector = Vec::new();
     for i in arr.iter() {
         vector.push(*i);
     }
     vector
}

fn vector_as_u8_4_array(vector: Vec<u8>) -> [u8;4] {
    let mut arr = [0u8;4];
    for i in (0..4) {
        arr[i] = vector[i];
    }
    arr
}

最佳答案

代码对我来说似乎很好,尽管有一个非常重要的安全事项需要注意:在 arr 未完全初始化时不会出现 panic 。在未初始化的内存上运行析构函数很容易导致未定义的行为,特别是,这意味着 into_iter 和它的 next 方法永远不应该 panic (我相信 0x2518122313403141 和的代码)。

也就是说,我们可以用一个函数来表达 enumerate/mem::* 习语: replace

for (idx, element) in $container.into_iter().enumerate() {
    ptr::write(&mut arr[idx], element);
}

虽然,我会把它写成:

for (place, element) in arr.iter_mut().zip($container.into_iter()) {
    ptr::write(place, element);
}

类似地,可以将一些迭代器的优点应用于 forget 专用版本:

fn array_to_vec(arr: &[u8]) -> Vec<u8> {
     arr.iter().cloned().collect()
}
fn vector_as_u8_4_array(vector: Vec<u8>) -> [u8;4] {
    let mut arr = [0u8;4];
    for (place, element) in arr.iter_mut().zip(vector.iter()) {
        *place = *element;
    }
    arr
}

虽然第一个写成 std::ptr::write 可能更好,第二个写成

let mut arr = [0u8; 4];
std::slice::bytes::copy_memory(&vector, &mut arr);
arr

尽管 that function 目前不稳定,因此只能在夜间使用。

关于rust - 将向量转换为数组并返回,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/29784502/

10-15 12:18