2015-10-19 89 views

回答

1

這一次使用collect

let strs: Vec<&str> = another_items.iter().map(|s| s as &str).collect(); 
2
another_items.iter().map(|item| item.deref()).collect::<Vec<&str>>() 

要使用deref()必須添加使用use std::ops::Deref

20

有不少方法可以做到這一點,一些有缺點,別人根本是更具可讀性對一些人。

此解引用s(這是&String類型)到String「右側的參考」,然後將其通過Deref性狀給str「右手側基準」解除引用,然後變回&str。這是在編譯器中很常見的東西,因此我認爲它是慣用的。

let v2: Vec<&str> = v.iter().map(|s| &**s).collect(); 

這裏Deref性狀的deref功能傳遞給map功能。它非常整潔,但需要use特性或完整的路徑。

let v3: Vec<&str> = v.iter().map(std::ops::Deref::deref).collect(); 

這已被棄用,你不應該這樣做,因爲它可以在未來與|s| s: &str(強制語法)來完成。

let v4: Vec<&str> = v.iter().map(|s| s as &str).collect(); 

這需要RangeFull切片String的(只是一個切片到整個String)和需要對它的引用。我認爲這很醜陋。

let v5: Vec<&str> = v.iter().map(|s| &s[..]).collect(); 

這是使用強制轉換到&String轉換成&str。將來也可以用s: &str表達式替換。

let v6: Vec<&str> = v.iter().map(|s| { let s: &str = s; s }).collect(); 

以下(感謝@休恩-dbaupp)使用AsRef性狀,其單獨存在於從所擁有的類型到它們各自的借類型映射。有兩種方法可以使用它,而且任何一個版本的漂亮都完全是主觀的。

let v7: Vec<&str> = v.iter().map(|s| s.as_ref()).collect(); 

let v8: Vec<&str> = v.iter().map(AsRef::as_ref).collect(); 

我的底線是使用v8解決方案,因爲它最明確地表達你想要什麼。

+2

顯式調用'deref'(特別是作爲一個自由函數)會讀取很奇怪的IMO,我個人覺得'v2'或'v5'更好。 (也可以使用'as_ref','v.iter()。map(| s | s.as_ref())...'這種形式的泛型轉換的典型方法,例如'std'中的許多函數採取'P:AsRef '。) – huon

+0

謝謝,你是完全正確的。 「AsRef」在這裏更合適。我更新了這篇文章 –

6

其他答案只是工作。我只是想指出的是,如果你想給Vec<String>轉換成Vec<&str>只將它傳遞給服用Vec<&str>作爲自變量的函數,考慮修改函數簽名爲:

fn my_func<T: AsRef<str>>(list: &[T]) { ... } 

代替:

fn my_func(list: &Vec<&str>) { ... } 

正如這個問題所指出的:Function taking both owned and non-owned string collections。通過這種方式,這兩種載體只需簡單地工作而不需要轉換。

0

這裏是另一種選擇:

use std::iter::FromIterator; 

let v = Vec::from_iter(v.iter().map(String::as_str)); 

注意String::as_str是穩定的,因爲鏽病1.7。