将向量转换为数组并返回
Convert vectors to arrays and back
我正在尝试找出最像 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
未完全初始化时不会出现恐慌。 运行 未初始化内存的析构函数很容易导致未定义的行为,特别是,这意味着 into_iter
和它的 next
方法永远不会恐慌(我相信这是不可能的enumerate
和 mem::*
部分迭代器在给定代码约束的情况下恐慌)。
也就是说,可以用一个函数表达 replace
/forget
成语:std::ptr::write
.
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);
}
类似地,可以将一些迭代器优点应用于 u8
专用版本:
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
}
虽然第一个最好写成arr.to_vec()
,第二个写成
let mut arr = [0u8; 4];
std::slice::bytes::copy_memory(&vector, &mut arr);
arr
虽然that function目前不稳定,因此只能在夜间使用。
我正在尝试找出最像 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
未完全初始化时不会出现恐慌。 运行 未初始化内存的析构函数很容易导致未定义的行为,特别是,这意味着 into_iter
和它的 next
方法永远不会恐慌(我相信这是不可能的enumerate
和 mem::*
部分迭代器在给定代码约束的情况下恐慌)。
也就是说,可以用一个函数表达 replace
/forget
成语:std::ptr::write
.
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);
}
类似地,可以将一些迭代器优点应用于 u8
专用版本:
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
}
虽然第一个最好写成arr.to_vec()
,第二个写成
let mut arr = [0u8; 4];
std::slice::bytes::copy_memory(&vector, &mut arr);
arr
虽然that function目前不稳定,因此只能在夜间使用。