在线观看www成人影院-在线观看www日本免费网站-在线观看www视频-在线观看操-欧美18在线-欧美1级

0
  • 聊天消息
  • 系統消息
  • 評論與回復
登錄后你可以
  • 下載海量資料
  • 學習在線課程
  • 觀看技術視頻
  • 寫文章/發帖/加入社區
會員中心
創作中心

完善資料讓更多小伙伴認識你,還能領取20積分哦,立即完善>

3天內不再提示

Rust代碼啟發之返回值異常錯誤處理

工程師鄧生 ? 來源:CrackingOysters ? 作者:CrackingOysters ? 2022-09-22 09:24 ? 次閱讀

編寫程序,錯誤處理是不可避免的。

程序員總是偏向正常的情況,而容易忽略有錯誤的情況。

返回值錯誤處理

最開始,錯誤是通過返回值來表示,比如非零表示錯誤,0表示成功。而處理錯誤的代碼類似

poYBAGMruXSAOsonAABERI2P8U0826.jpg

這樣的代碼,錯誤處理代碼和業務邏輯交織在一起,也容易忽略處理錯誤。以及把返回值只用于錯誤返回,有點浪費的感覺。因為很多時候把計算結果作為返回值,更符合思考的邏輯。

異常錯誤處理

后面出現了異常的方式,在出錯的時候,拋出異常。異常一層一層往上拋,如果沒有處理異常,那么程序就會被terminate. 比如C++Java采用這種方式。

使用異常的代碼類似

poYBAGMruYaARsVnAAAmqblhFCU436.jpg

看起來錯誤處理代碼與業務邏輯分開,比較清晰。但有如下的不足,

錯誤處理也容易被忽略,不寫相應的catch,

上層調用者在嵌套很多層的時候,很難知道底層是否會拋異常。

這么寫代碼,在catch的地方,分不清楚是在哪里出了錯誤,step1?step3?

注:python把異常還用于程序控制流改變,如StopInteractionException用于跳出循環。

Java里異常還分checked exception和unchecked exception。checked exception是必須要處理的異常,從而可以避免被忽略。但checked exception有其局限性,比如添加新的checked exception,會改變接口簽名,變得不能向前兼容。

綜上,我們需要一種錯誤處理

避免無意識地忽略。

可閱讀性強。

其中返回值和異常都可能會被無意識忽略??勺x性,異常好于返回值,且避免占用了返回值。而不可忽略的Java checked exception有它自己的問題。

就沒有其他更好的方式了嗎?Rust給出了它的答案,使用Result 類型。

什么是Result和類型?

Result的完整形態是Result,其中T和E是泛型參數。不懂泛型不重要,這里跟泛型沒有關系。我們要知道的是Result是兩個類型的集合:

一個是沒有錯誤時的計算結果

一個是出錯時,要返回的錯誤

第一點,我們可以看到,現在返回值可以用于返回函數計算的結果了,沒有被錯誤占領。

第二點,因為返回的值又不是計算結果,所以程序員不能直接使用返回值,需要先檢查具體的類型,沒有出錯時,才能使用計算結果。這樣又避免了無意識的忽略錯誤。

我們可以簡陋地認為Result類型,是C++里面的tag union,即包含一個tag的union。其中tag是錯誤標記,如果是0表示成功,非零表示錯誤,而union則存放著具體的錯誤或者具體的計算結果。(很多時候Result,稱作是和類型 sum type)

可以避免無意識地忽略錯誤,那么可讀性呢?

因為返回值不是計算結果,需要檢查一下才能繼續下一步,這不就跟錯誤返回值一樣了嗎?

注:先把話說明,沒有錯誤處理的代碼是可讀性最好的。因為只有happy path,第一步,第二步等等。但我們討論在可能出錯的時候的可讀性。

Result和類型的代碼可以是

pYYBAGMruZqAb4TrAAAkG9L3Hh0254.jpg

哇咔咔,這看上去可讀性很差那。實話說,這么寫的代碼的確沒有什么可讀性。

但Rust提供了另外一個寫法,如下

let res = step1()?;let res= step2()?;let res = step3()?;

這個寫法看起來很像異常的情況。業務邏輯和錯誤處理沒有交織在一起。

眼尖的讀者會發現每個函數都有個問號?。而錯誤處理就藏在?后面。

問號的存在,讓Rust自動幫你檢查返回值,在出錯的時候直接返回錯誤,不再繼續往下走了。問號可以展開為如下的形式(簡化版本,方便理解,實際版本請看官方文檔),

pYYBAGMrubWAA8t2AAAb_QfNdaI791.jpg

到這里,我們可以看到Rust的創新點在于將錯誤與計算結果放在了返回值,而不是單純地返回錯誤,或者返回計算結果和從第三個路徑返回異常。并且提供了問號和組合子來簡寫錯誤處理。所以同時提供了避免無意識忽略錯誤和提供可讀性。

但錯誤處理遠遠不止這點內容。在我寫了GitHub的webhook微服務 https://github.com/Celthi/github-webhook-gateway 以后,我發現寫了一大坨下面的代碼

poYBAGMrugGABAnhAAD-8POIEvE692.jpg

寫成這樣,說明我對Rust的錯誤處理仍然沒有理解到位,于是我試著重構這段代碼,并提了個問題How reduce the nested if and indents?

經過重構以后,我發現了如下的一些情況

有時候只想處理成功的情況,我稱之為“最大努力做事”。所以代碼邏輯是這樣

poYBAGMruhSAQQ8nAAAoKm9J6kw469.jpg

這也是我自己代碼那么多縮進的原因。它可以通過如下方式來改善,

方式一、首先先把代碼段提到一個單獨的函數post_sending_task(),然后將返回值改成Result,所以調用的地方代碼是

let _ = best_delivery(); //這里使用使用_,說明我們不關心失敗的情況

在這個best_delivery()里面,我們就可以使用問號表達式了。

方式二、使用組合子,如將Option轉換成Result,從而可以使用問號,如

let res = get_something().ok_or_else(|| err)?;

這里ok_or_else是option上的組合子。什么是組合子,簡單理解是將東西組合在一起的函數。至于”子“,一種稱謂罷了,要說相似的話,第一反應類似套接字里面的”字“的功能。

方式三、提前返回。通過反轉if的條件,提前返回,比如,

poYBAGMrukGAEExGAAAUCHOhdbI596.jpg

提前返回沒有問號那么可讀性強,但是減少了縮進的層數。

方式四、如果獲取結果的同時必須處理錯誤的情況,那么使用下面的形式,
poYBAGMruliAas22AAAiGpGUc8s587.jpg

注意,問號表達式是適合于獲取結果且不處理錯誤,直接往上拋。

經過這四個個方式的改善,我的代碼可讀性提高了,變成了

pYYBAGMrunCAFYXtAADRtwuGU7w403.jpg

錯誤處理與日志、錯誤報告

錯誤處理的時候,通常要寫日志。但是錯誤處理和日志是兩碼事。不是所有的錯誤處理都要寫日志,而且不同的錯誤,寫到的日志級別是不一樣的,如調試,信息,錯誤,嚴重等等級別。

錯誤處理是處理出錯的情況,而日志是記錄感興趣的信息。它們有重合,但是關注點不一樣。以后再寫文章。

錯誤報告(error report)跟錯誤處理也是兩碼事,雖然經常關聯在一起,也留作以后再寫文章。





審核編輯:劉清

聲明:本文內容及配圖由入駐作者撰寫或者入駐合作網站授權轉載。文章觀點僅代表作者本人,不代表電子發燒友網立場。文章及其配圖僅供工程師學習之用,如有內容侵權或者其他違規問題,請聯系本站處理。 舉報投訴
  • JAVA
    +關注

    關注

    19

    文章

    2969

    瀏覽量

    104789
  • python
    +關注

    關注

    56

    文章

    4797

    瀏覽量

    84727
  • Rust
    +關注

    關注

    1

    文章

    229

    瀏覽量

    6614

原文標題:Rust代碼啟發之錯誤處理

文章出處:【微信號:Rust語言中文社區,微信公眾號:Rust語言中文社區】歡迎添加關注!文章轉載請注明出處。

收藏 人收藏

    評論

    相關推薦

    Rust語言中錯誤處理的機制

    Rust語言中,錯誤處理是一項非常重要的任務。由于Rust語言采用靜態類型檢查,在編譯時就能發現很多潛在的錯誤,這使得程序員能夠更加自信和高效地開發程序。然而,即使我們在編譯時盡可能
    的頭像 發表于 09-19 14:54 ?1432次閱讀

    如何處理STM32的HAL庫函數返回異常問題?

    (1)官方提供的例程里面,例如返回的結果不是 HAL_OK 的結果,一般直接跳轉到 錯誤處理的函數里面了。這樣寫的目的是給開發者根據實際情況自己寫異常處理
    發表于 04-17 06:39

    嵌入式C編程常用的異常錯誤處理

    嵌入式C編程中,異常錯誤處理是確保系統穩定性和可靠性的重要部分。以下是一些常見的異常錯誤處理方法及其詳細說明和示例: 1. 斷言 (Assertions) 斷言用于在開發階段捕獲程
    發表于 08-06 14:32

    main函數返回值的認知

    。main也可以使用return向操作系統返回一個,使用操作系統的命令可以檢測main的返回值。一般約定在main返回0時,表示程序運行過程中沒有出現
    發表于 10-24 11:08

    WebApi接口返回值的四種類型

    Webapi的接口返回值主要有四種類型 void無返回值 IHttpActionResult HttpResponseMessage 自定義類型 void無返回值 大家都知道void聲明的是一個無
    發表于 11-27 14:52 ?1.3w次閱讀

    C語言程序開發中關于函數返回值的問題

    C語言函數可以通過返回值表示輸出結果,例如 log() 函數的返回值會根據不同的輸入,返回不同的。再比如,我們定義一個函數 myopen(),用于打開某個文件,那么,這個函數要么能夠
    發表于 09-06 10:01 ?954次閱讀

    return-函數的返回值是什么

    return關鍵字后接變量名或表達式可以將函數的計算結果返回到調用處。變量或表達式等同于接收果汁、豆漿的杯子。如果函數沒有返回值,return可以省略不寫。沒有返回值的意思是程序執行完畢之后,不需要給調用函數處提供數據。
    的頭像 發表于 02-23 10:52 ?1227次閱讀
    return-函數的<b class='flag-5'>返回值</b>是什么

    什么是函數的返回值

    函數的返回值是函數被調用后,執行所調用函數內代碼后所得出的結果,并且將返回給主函數的
    的頭像 發表于 04-04 17:21 ?4997次閱讀

    rust語言基礎學習: rust中的錯誤處理

    錯誤是軟件中不可避免的,所以 Rust 有一些處理出錯情況的特性。在許多情況下,Rust 要求你承認錯誤的可能性,并在你的
    的頭像 發表于 05-22 16:28 ?2128次閱讀

    ARM異常返回值的合法有哪些?各返回值分別代表什么?

    ARM異常返回值的合法有哪些?各返回值分別代表什么? ARM異常返回值的合法
    的頭像 發表于 10-19 16:36 ?899次閱讀

    C語言中的錯誤處理機制解析

    C 語言不提供對錯誤處理的直接支持,但是作為一種系統編程語言,它以返回值的形式允許您訪問底層數據。
    的頭像 發表于 02-26 11:19 ?519次閱讀

    閉包在錯誤處理中的應用模式探索

    通過在函數和方法中返回錯誤對象作為它們的唯一或最后一個返回值——如果返回 nil,則沒有錯誤發生——并且主調(calling)函數總是應該檢
    的頭像 發表于 03-15 09:57 ?442次閱讀

    一站式統一返回值封裝、異常處理、異常錯誤碼解決方案—最強的Sping Boot接口優雅響應處理

    1. 前言 統一返回值封裝、統一異常處理異常錯誤碼體系的意義在于提高代碼的可維護性和可讀性,使
    的頭像 發表于 06-20 15:42 ?551次閱讀

    HTTP相關返回值異常如何解決(上篇)

    ? 今天我們講講HTTP相關返回值異常如何解決(實例持續更新中) HTTP介紹 HTTP(超文本傳輸協議,Hypertext Transfer Protocol)是用于在網絡上進行數據交換的應用層
    的頭像 發表于 10-20 16:40 ?311次閱讀
    HTTP相關<b class='flag-5'>返回值</b><b class='flag-5'>異常</b>如何解決(上篇)

    socket編程中的錯誤處理技巧

    錯誤處理能夠確保程序在遇到異常情況時不會崩潰,而是能夠優雅地處理問題。 提升用戶體驗 :通過適當的錯誤處理,可以給用戶提供清晰的錯誤信息
    的頭像 發表于 11-01 17:47 ?867次閱讀
    主站蜘蛛池模板: 狠狠色噜噜狠狠狠狠黑人| 天天爽夜夜爽人人爽曰喷水| 日本乱理论片免费看| 三级在线观看视频网站| 四虎永久精品免费观看| 色老板在线视频一区二区| 色天使色婷婷在线影院亚洲| 日韩第五页| 两性午夜欧美高清做性| 国产特黄一级片| 亚洲爽爽网| 久草免费色站| 成年人啪啪网站| 国产精品自在线天天看片 | 亚洲国产欧美日韩一区二区三区| 一级国产特黄aa大片| 天堂网中文在线| 中日韩在线视频| 五月婷婷免费视频| 人成电影免费观看在线| 天天性视频| 欧美日韩中文字幕| 国产人免费人成免费视频| 在线午夜影院| 久久99精品久久久久久秒播| 黄色网在线播放| 一级毛毛片毛片毛片毛片在线看| 色婷婷在线视频| 国产专区青青草原亚洲| 天天爽夜夜爽人人爽曰喷水| 草久久久久| 国产精品乱码高清在线观看| 四虎影永久在线观看网址| 久久夜色tv网站| 狠狠的日视频| 亚洲dv| 国产婷婷综合在线精品尤物| 亚洲天堂bt| 色老二精品视频在线观看| 国产美女精品视频免费观看| 日本黄色录象|