2015-04-21 86 views
8

我正在嘗試將矢量轉換爲數組並將其轉換爲最類似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 
} 
+3

關於標準術語的一點:'Vec ':vector; '[T]':切片; '[T; N]':數組。 –

+5

要從切片(或切片陣列)切換到「Vec」,請使用['From'](http://doc.rust-lang.org/std/convert/trait.From.html): 'let z:Vec <_> = From :: from(&array [..])' – Shepmaster

+0

謝謝你們兩位的輸入。非常感激。 – dirvine

回答

7

代碼似乎沒什麼問題,但有一個非常重要的安全一點要注意:不能有任何恐慌,而arr沒有完全初始化。在未初始化的內存上運行析構函數很容易導致未定義的行爲,尤其是,這意味着它的方法不應該恐慌(我相信,考慮到約束條件,迭代器的enumeratemem::*部分不可能發生恐慌的代碼)。

也就是說,可以用單個函數來表示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不穩定,因此只能在夜間使用。

相關問題