2016-12-18 74 views
1

這是一個絕對的初學者問題,但在搜索半小時後我找不到任何有用的東西。我有鏽跡1.7.0和驗證碼:如何添加兩個Rust數組元素?

type coord = [i64; 3]; 

// add two coordinates ("vectors") pointwise, that is 
// if z = add(a, b) then z[i] = a[i] + b[i] for i=0..2 
fn add(a: coord, b: coord) -> coord { 
    //??? 
} 

我第一次嘗試的明顯的一點就是a.zip(b).map(|(u,v)| u+v)但這並不工作(無法壓縮陣列),也不a.iter().zip(b.iter()).map(|(u,v)| u+v),因爲它不能轉換迭代器回到數組。我可以看到爲什麼這一般不起作用,但在這種情況下,我們知道兩個事物的長度是相同的。

現在我在做

fn add(a: coord, b: coord) -> coord { 
    let mut z: coord = [0, 0, 0]; 
    for i in 0..2 { 
     z[i] = a[i] + b[i]; 
    } 
    z 
} 

但相比之下長相醜陋。我錯過了什麼?

+3

注意,'0..2'應該是'0。 .3'在你的代碼中。 – wimh

+0

「醜陋」是主觀的,但我發現明確的'對於0..3中的i'比建議的替代方案更可讀 –

回答

3

一個簡單的方法是使用enumerate迭代方法來生成索引,並填寫z了「明顯」的方式,通過分配到所獲得的指標:

type Coord = [i64; 3]; 

fn add(a: Coord, b: Coord) -> Coord { 
    let mut z: Coord = [0, 0, 0]; 
    for (i, (aval, bval)) in a.iter().zip(&b).enumerate() { 
     z[i] = aval + bval; 
    } 
    z 
} 

fn main() { 
    let x: Coord = [1, 2, 3]; 
    let y: Coord = [1, 1, 1]; 
    assert!(add(x, y) == [2, 3, 4]); 
} 

生鏽,我們可以注意到做得更好iter()產生引用到數組中,並且iter_mut()可用於產生可變引用。這導致代碼非常相似,你試圖寫什麼:

fn add(a: Coord, b: Coord) -> Coord { 
    let mut z: Coord = [0, 0, 0]; 
    for ((zref, aval), bval) in z.iter_mut().zip(&a).zip(&b) { 
     *zval = aval + bval; 
    } 
    z 
} 

如果寫入z的這種模式具有不同的操作再次出現,你可以抽象創造新的Coord與數據轉換成通用的功能加油吧:

fn new_coord_from<F: Iterator<Item=i64>>(src: F) -> Coord { 
    let mut result = [0; 3]; 
    for (rref, val) in result.iter_mut().zip(src) { 
     *rref = val; 
    } 
    result 
} 

add那麼看起來就像是我們希望它想:

fn add(a: Coord, b: Coord) -> Coord { 
    new_coord_from(a.iter().zip(&b).map(|(a, b)| a + b)) 
} 
+0

小後續:如果我想聲明一個函數'fn cmap(a:Coord,b :Coord,f:F) - > Coord {new_coord_from(a.iter()。zip(&b).map(f)); }'也抽象出iter/zip部分,所以我可以聲明'fn add(a:Coord,b:Coord) - > Coord {cmap(a,b,|(a,b)| a + b)}' - 我需要爲F輸入哪種類型? – Bristol

+1

@Bristol Ass目前編寫的,它將是'cmap i64>(a:Coord,b:Coord,f:F) - > Coord'。然而,我希望擺脫引用並使'F'接收兩個數字而不是元組:'fn cmap i64>(a:Coord,b:Coord, f:F) - > Coord {new_coord_from(a.iter()。zip(&b).map(|(x,y)| f(* x,* y)))}'。然後,add的定義歸結爲最簡單的形式:cmap(a,b,| x,y | x + y)或者甚至是cmap(a,b,i64 :: add) '使用std :: ops :: Add'添加'特徵到範圍中)。 – user4815162342