2016-02-17 15 views
0

之一,我有兩個瓶蓋來捕獲同一Vec,我不知道如何在慣用鏽這樣寫:捕獲相同的變量在多個瓶蓋

use std::error; 

fn get_token -> Box<Vec<u8>>() {...} 
fn do_stuff(file: &str) -> std::io::Result<i32> {...} 
fn do_other_stuff(a: &str, a: &str) -> std::io::Result<i32> {...} 

enum MyError { 
    IoError { token: Vec<u8>, reason: String), 
} 

fn consumer() -> Result<MyError,()> { 
    let token = get_token(); 

    try!(do_stuff("a") 
     .map_err(|e| MyError::IoError { token: token, reason: "foo".to_str() })); 
    try!(do_other_stuff("b", "c") 
     .map_err(|e| MyError::IoError { token: token, reason: "bar".to_str() })); 
} 

我可以match更換map_err電話表達式,但我真的很難過這個:我如何將Vec傳遞給多個閉包?

+2

請問我爲什麼輸出'get_token','Box >'而不是'Vec ' –

回答

3

首先:請務必在未來提供一個MCVE,這不是有樂趣能夠再現你的問題之前解決語法錯誤:http://is.gd/tXr7WK

鏽不知道的唯一途徑第二次關閉可以運行,如果第一次關閉沒有運行並且永遠不會運行。您可以等待let/else RFC被接受,實施並且穩定下來,或者您可以逐步創建錯誤,首先創建一個內部閉包,該內部閉包針對該錯誤類型執行所有操作,而不使用token,然後運行閉包,然後將該錯誤映射到您的自定義錯誤類型。

|| -> _ { 
    try!(do_stuff("a").map_err(|e| ("foo".to_owned(), e))); 
    try!(do_other_stuff("b","c").map_err(|e| ("bar".to_owned(), e))); 
    Ok(()) 
}().map_err(|(reason, e)| MyError::IoError{ token: token, reason: reason }) 

有事情如封閉要求我們指定它返回一些與-> _奇怪的東西,但我不知道它是什麼。

+0

謝謝,下次我會用操場發帖子。道歉。 –

+0

不錯的解決方案......但是這是「||」 - > _ {...}()'pattern perl like! –

2

您可以使用and_then()組合子,以避免額外關閉:

try!(do_stuff("a").map_err(|_| "foo") 
     .and_then(|_| 
      do_other_stuff("b","c").map_err(|_| "bar") 
     ) 
     .map_err(|e| MyError::IoError{token:token,reason:e.into()}) 
); 
3

更直接是隻不使用try!或關閉:

if let Err(e) = do_stuff("a") { 
    return Err(MyError::IoError{token: token, reason: "foo".to_owned()}); 
} 
if let Err(e) = do_other_stuff("b", "c") { 
    return Err(MyError::IoError{token: token, reason: "bar".to_owned()}); 
} 

這讓像你想它鏽病進行簡單分析並且比通過籃球跳舞更可讀。

+0

與此相關的問題是,您放棄了「確定」的值,但是由於無論如何在這個問題中這不是必需的,您的答案是最漂亮的。 –

+1

@ker如果你想得到'Ok'值,你可以'匹配'。 – Veedrac

相關問題