2016-04-27 19 views
11

在Rust中,我相信處理可恢復錯誤的慣用方法是使用Result。例如該函數顯然是慣用:如果成功,返回函數中的錯誤而沒有結果的慣用方法是什麼?

fn do_work() -> Result<u64, WorkError> {...} 

當然,也有具有單一的,明顯的,故障狀態,並因此使用的選項類型,而不是功能。一個慣用的例子是:

fn do_work() -> Option<u64> 

這一切都直接在文檔中解決。然而,我對功能失敗的情況感到困惑,但成功時卻沒有意義。比較以下兩個函數:

fn do_work() -> Option<WorkError> 
// vs 
fn do_work() -> Result<(), WorkError> 

我只是不確定這些中哪一個更具慣用性,或者在現實世界中更常使用Rust代碼。我對這類問題的前往資源是Rust書,但我認爲這不在其「Error Handling」部分中提及。我還沒有與其他Rust文檔運氣很好。

當然這看起來很主觀,但我正在尋找權威的來源,要麼說明哪種形式是慣用的,要麼說明爲什麼一種形式比另一種形式更好(或更差)。 (我也很好奇,這種慣例是如何與其他語言相比,像Go和Haskell那樣大量使用「錯誤作爲數值」)。

+2

我是'結果<(), Error>'方面的事情..我通常將這些作爲我自己的類型。我很想聽聽其他人說什麼。我這樣做,但是因爲'try!'宏仍然可以很好地播放它。 –

回答

17

使用fn do_work() -> Result<(), WorkError>

Result<(), WorkError>表示您希望完成工作,但可能會失敗。

Option<WorkError>表示您想要得到一個錯誤,但它可能不存在。

您可能希望完成這項工作,但在編寫do_work()時不會出現錯誤,因此Result<(), WorkError>是更好的選擇。

我期望Option<WorkError>只用於像fn get_last_work_error() -> Option<WorkError>這樣的情況。

+0

我不認爲我不同意,我認爲Result <(),WorkError>稍好一點。但是,我想知道是否有任何「官方」來源以任何方式支持您的答案? – Others

+0

@其他既然'do_work'本身就是一個概念性的例子,我不認爲會有任何正式的約定。但是,您可以瞭解標準庫中的習慣用法,例如:https://doc.rust-lang.org/nightly/std/io/trait.Read.html#method.read_exact – WiSaGaN

+4

@其他整個標準庫當可能失敗的操作不會返回任何有用的東西(例如'std :: io'和'std :: fs'的許多函數)時,它會普遍地使用'Result <(), _>'。這是正確的選擇。 – huon

4

鐵鏽是「相當強烈的類型」(請,請不要打電話給我如何衡量輸入語言的強度是多麼強烈......)。我的意思是,Rust通常爲您提供讓類型「爲您說話」並記錄您的代碼的工具,因此使用此功能編寫可讀代碼是習慣用法。

換句話說,你所問的問題應該是「哪種類型代表最好的功能對讀取其簽名的人是什麼?」。

對於Result<(), Workerror>你可以看到直from the docs

結果是表示無論成功(OK)或失敗(ERR)

那麼有型,專門針對你的情況,這意味着你的函數如果成功(如Ok<()>)或WorkError(如果發生錯誤)(Err<WorkError>),則不返回任何內容。這是您在問題中描述函數的方式的代碼中的一種非常直接的表示形式。

比較這對Option<WorkError>Option<()>

類型選項表示可選值:每一個選項或者是一些和包含值或無,並且不

在你的情況Option<WorkError>會對讀者說:「這個函數應該返回一個WorkError,但它可能不會返回」。你可以證明「沒有返回」的情況意味着這個函數實際上是成功的,但是從單獨的類型來看,這並不是很明顯。

Option<()>說:「這個功能可以返回什麼或沒有有意義的回報」,它可以是一個合理的事情,也就是說,當WorkError不包含任何其他信息(如錯誤類型或錯誤消息)和它實際上只是一種方式說「發生了錯誤」。在這種情況下,一個簡單的bool包含相同的信息...否則,Result可讓您返回一些與該錯誤相關的更多信息。

相關問題