2017-07-13 36 views
0

我有一個程序,其中我fold字符串的向量,增加一個值,並建立另一個向量。事情是這樣的:什麼是非破壞性地向矢量附加值的慣用方式?

struct Widget { foo: isize, text: &'static str } 
let foos = vec!["a", "b", "c"]; 
let (final, ws) = foos.iter().fold((0, widgets), |(x, ws), text| { 
    (x+1, Widget { foo: x, text: text }) 
}); 

與上面的代碼的問題是,我需要追加新的小工具,ws,不到位的ws返回新的widget。爲此,我需要一種非破壞性地向矢量附加值的方法。這裏的簽名,大致的功能我在尋找:

fn append<T>(vec: Vec<T>, item: T) -> Vec<T>

我似乎無法找到這樣的功能。看起來這個(或作爲Vec上的一個方法)對於Rust來說非常習慣,但它不在那裏。有沒有另外一種更通俗的方式來實現它,或者是否有像上面這樣的函數?

+0

我沒了解清楚。 – Stargateur

+0

你能否通過非破壞性的方式闡明你的意思? – Shepmaster

+2

'fold'似乎並不是這裏的正確工具。你應該使用'enumerate'生成'x'索引,'map'然後用'collect'來創建小部件的向量。 – interjay

回答

2

非破壞性的值附加到矢量

這是不可能的。修改矢量...修改它。你無法解決這個問題。您可以選擇clone這個向量,這樣可以避免突變載體的原始對象。你仍然需要發生變異的克隆,但是:

let things = vec![1]; 
let things2 = { 
    let mut tmp = things.clone(); 
    tmp.push(2); 
    tmp 
}; 

如果與原始載體完成,你可以重複使用它:

let things = vec![1]; 
let things2 = { 
    let mut tmp = things; 
    tmp.push(2); 
    tmp 
}; 

這可以提取到您所需的功能簽名:

fn append(vec: Vec<i32>, item: i32) -> Vec<i32> { 
    let mut vec = vec; 
    vec.push(item); 
    vec 
}; 

這將慣用但是等效地寫爲

fn append(mut vec: Vec<i32>, item: i32) -> Vec<i32> { 
    vec.push(item); 
    vec 
}; 

let things = vec![1]; 
let things2 = append(things.clone(), 2); 
let things2 = append(things, 2); 

這樣看來,(或者說,這個是Vec的方法)將是非常地道的生鏽

不是真的 - 有這個方法的簽名,你必須擁有Vec。只有對Vec有可變參考才更常見,它提供了一組不同的功能。

有人對Vec實施了Add,這可能允許像let things2 = things + 2這樣的東西,但我不知道那是去哪兒的。


對於它的價值,我會寫你的代碼爲:

let foos = ["a", "b", "c"]; 

let ws: Vec<_> = foos.iter() 
    .enumerate() 
    .map(|(i, text)| Widget { foo: i as isize, text }) 
    .collect(); 
相關問題