<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                ??一站式輕松地調用各大LLM模型接口,支持GPT4、智譜、豆包、星火、月之暗面及文生圖、文生視頻 廣告
                使用有兩個分支的if語句,只是我的代碼可以達到無懈可擊的其中一個原因。這樣寫if語句的思路,其實包含了使代碼可靠的一種通用思想:窮舉所有的情況,不漏掉任何一個。 程序的絕大部分功能,是進行信息處理。從一堆紛繁復雜,模棱兩可的信息中,排除掉絕大部分“干擾信息”,找到自己需要的那一個。正確地對所有的“可能性”進行推理,就是寫出無懈可擊代碼的核心思想。這一節我來講一講,如何把這種思想用在錯誤處理上。 錯誤處理是一個古老的問題,可是經過了幾十年,還是很多人沒搞明白。Unix的系統API手冊,一般都會告訴你可能出現的返回值和錯誤信息。比如,Linux的[read](http://man7.org/linux/man-pages/man2/read.2.html)系統調用手冊里面有如下內容: ~~~ RETURN VALUE? On success, the number of bytes read is returned... On error, -1 is returned, and errno is set appropriately. ERRORS EAGAIN, EBADF, EFAULT, EINTR, EINVAL, ... ~~~ 很多初學者,都會忘記檢查`read`的返回值是否為-1,覺得每次調用`read`都得檢查返回值真繁瑣,不檢查貌似也相安無事。這種想法其實是很危險的。如果函數的返回值告訴你,要么返回一個正數,表示讀到的數據長度,要么返回-1,那么你就必須要對這個-1作出相應的,有意義的處理。千萬不要以為你可以忽視這個特殊的返回值,因為它是一種“可能性”。代碼漏掉任何一種可能出現的情況,都可能產生意想不到的災難性結果。 對于Java來說,這相對方便一些。Java的函數如果出現問題,一般通過異常(exception)來表示。你可以把異常加上函數本來的返回值,看成是一個“union類型”。比如: ~~~ String foo() throws MyException { ... } ~~~ 這里MyException是一個錯誤返回。你可以認為這個函數返回一個union類型:`{String, MyException}`。任何調用`foo`的代碼,必須對MyException作出合理的處理,才有可能確保程序的正確運行。Union類型是一種相當先進的類型,目前只有極少數語言(比如Typed Racket)具有這種類型,我在這里提到它,只是為了方便解釋概念。掌握了概念之后,你其實可以在頭腦里實現一個union類型系統,這樣使用普通的語言也能寫出可靠的代碼。 由于Java的類型系統強制要求函數在類型里面聲明可能出現的異常,而且強制調用者處理可能出現的異常,所以基本上不可能出現由于疏忽而漏掉的情況。但有些Java程序員有一種惡習,使得這種安全機制幾乎完全失效。每當編譯器報錯,說“你沒有catch這個foo函數可能出現的異常”時,有些人想都不想,直接把代碼改成這樣: ~~~ try { foo(); } catch (Exception e) {} ~~~ 或者最多在里面放個log,或者干脆把自己的函數類型上加上`throws Exception`,這樣編譯器就不再抱怨。這些做法貌似很省事,然而都是錯誤的,你終究會為此付出代價。 如果你把異常catch了,忽略掉,那么你就不知道foo其實失敗了。這就像開車時看到路口寫著“前方施工,道路關閉”,還繼續往前開。這當然遲早會出問題,因為你根本不知道自己在干什么。 catch異常的時候,你不應該使用Exception這么寬泛的類型。你應該正好catch可能發生的那種異常A。使用寬泛的異常類型有很大的問題,因為它會不經意的catch住另外的異常(比如B)。你的代碼邏輯是基于判斷A是否出現,可你卻catch所有的異常(Exception類),所以當其它的異常B出現的時候,你的代碼就會出現莫名其妙的問題,因為你以為A出現了,而其實它沒有。這種bug,有時候甚至使用debugger都難以發現。 如果你在自己函數的類型加上`throws Exception`,那么你就不可避免的需要在調用它的地方處理這個異常,如果調用它的函數也寫著`throws Exception`,這毛病就傳得更遠。我的經驗是,盡量在異常出現的當時就作出處理。否則如果你把它返回給你的調用者,它也許根本不知道該怎么辦了。 另外,try { ... } catch里面,應該包含盡量少的代碼。比如,如果`foo`和`bar`都可能產生異常A,你的代碼應該盡可能寫成: ~~~ try { foo(); } catch (A e) {...} try { bar(); } catch (A e) {...} ~~~ 而不是 ~~~ try { foo(); bar(); } catch (A e) {...} ~~~ 第一種寫法能明確的分辨是哪一個函數出了問題,而第二種寫法全都混在一起。明確的分辨是哪一個函數出了問題,有很多的好處。比如,如果你的catch代碼里面包含log,它可以提供給你更加精確的錯誤信息,這樣會大大地加速你的調試過程。
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看