2017-03-21 72 views

回答

20

正如你可能已經注意到的,Rust沒有例外。它有恐慌,但它們的功能是有限的(它們不能攜帶結構化信息),並且它們用於錯誤處理是不鼓勵的(它們意味着不可恢復的錯誤)。

在Rust中,錯誤處理使用Result。一個典型的例子是:

fn halves_if_even(i: i32) -> Result<i32, Error> { 
    if i % 2 == 0 { Ok(i/2) } else { Err(/* something */) } 
} 

fn do_the_thing(i: i32) -> Result<i32, Error> { 
    let i = match halves_if_even(i) { 
     Ok(i) => i, 
     e => return e, 
    }; 

    // use `i` 
} 

這是偉大的,因爲:

  • 編寫代碼時,你可以不小心忘了處理錯誤,
  • 閱讀代碼的時候可以立即看到這裏有可能出現錯誤。

然而,這並不理想,因爲它非常冗長。這是問號運營商?進來

以上可以改寫爲:

fn do_the_thing(i: i32) -> Result<i32, Error> { 
    let i = halves_if_even(i)?; 

    // use `i` 
} 

這是更爲簡潔。

什麼?在這裏所做的相當於上面的match聲明。簡而言之:如果確定,則解包Result,如果不是,則返回,如果不是,則返回

這有點神奇,但錯誤處理需要一些魔法來減少樣板,並且與例外情況不同,它可以立即看到哪些函數調用可能會或可能不會出錯:那些裝飾有?的函數。