<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>

                ThinkChat2.0新版上線,更智能更精彩,支持會話、畫圖、視頻、閱讀、搜索等,送10W Token,即刻開啟你的AI之旅 廣告
                有些人以為寫很多注釋就可以讓代碼更加可讀,然而卻發現事與愿違。注釋不但沒能讓代碼變得可讀,反而由于大量的注釋充斥在代碼中間,讓程序變得障眼難讀。而且代碼的邏輯一旦修改,就會有很多的注釋變得過時,需要更新。修改注釋是相當大的負擔,所以大量的注釋,反而成為了妨礙改進代碼的絆腳石。 實際上,真正優雅可讀的代碼,是幾乎不需要注釋的。如果你發現需要寫很多注釋,那么你的代碼肯定是含混晦澀,邏輯不清晰的。其實,程序語言相比自然語言,是更加強大而嚴謹的,它其實具有自然語言最主要的元素:主語,謂語,賓語,名詞,動詞,如果,那么,否則,是,不是,…… 所以如果你充分利用了程序語言的表達能力,你完全可以用程序本身來表達它到底在干什么,而不需要自然語言的輔助。 有少數的時候,你也許會為了繞過其他一些代碼的設計問題,采用一些違反直覺的作法。這時候你可以使用很短注釋,說明為什么要寫成那奇怪的樣子。這樣的情況應該少出現,否則這意味著整個代碼的設計都有問題。 如果沒能合理利用程序語言提供的優勢,你會發現程序還是很難懂,以至于需要寫注釋。所以我現在告訴你一些要點,也許可以幫助你大大減少寫注釋的必要: 1. 使用有意義的函數和變量名字。如果你的函數和變量的名字,能夠切實的描述它們的邏輯,那么你就不需要寫注釋來解釋它在干什么。比如: ~~~ // put elephant1 into fridge2 put(elephant1, fridge2); ~~~ 由于我的函數名`put`,加上兩個有意義的變量名`elephant1`和`fridge2`,已經說明了這是在干什么(把大象放進冰箱),所以上面那句注釋完全沒有必要。 2. 局部變量應該盡量接近使用它的地方。有些人喜歡在函數最開頭定義很多局部變量,然后在下面很遠的地方使用它,就像這個樣子: ~~~ void foo() { int index = ...; ... ... bar(index); ... } ~~~ 由于這中間都沒有使用過`index`,也沒有改變過它所依賴的數據,所以這個變量定義,其實可以挪到接近使用它的地方: ~~~ void foo() { ... ... int index = ...; bar(index); ... } ~~~ 這樣讀者看到`bar(index)`,不需要向上看很遠就能發現`index`是如何算出來的。而且這種短距離,可以加強讀者對于這里的“計算順序”的理解。否則如果index在頂上,讀者可能會懷疑,它其實保存了某種會變化的數據,或者它后來又被修改過。如果index放在下面,讀者就清楚的知道,index并不是保存了什么可變的值,而且它算出來之后就沒變過。 如果你看透了局部變量的本質——它們就是電路里的導線,那你就能更好的理解近距離的好處。變量定義離用的地方越近,導線的長度就越短。你不需要摸著一根導線,繞來繞去找很遠,就能發現接收它的端口,這樣的電路就更容易理解。 3. 局部變量名字應該簡短。這貌似跟第一點相沖突,簡短的變量名怎么可能有意義呢?注意我這里說的是局部變量,因為它們處于局部,再加上第2點已經把它放到離使用位置盡量近的地方,所以根據上下文你就會容易知道它的意思: 比如,你有一個局部變量,表示一個操作是否成功: ~~~ boolean successInDeleteFile = deleteFile("foo.txt"); if (successInDeleteFile) { ... } else { ... } ~~~ 這個局部變量`successInDeleteFile`大可不必這么啰嗦。因為它只用過一次,而且用它的地方就在下面一行,所以讀者可以輕松發現它是`deleteFile`返回的結果。如果你把它改名為`success`,其實讀者根據一點上下文,也知道它表示"success in deleteFile"。所以你可以把它改成這樣: ~~~ boolean success = deleteFile("foo.txt"); if (success) { ... } else { ... } ~~~ 這樣的寫法不但沒漏掉任何有用的語義信息,而且更加易讀。`successInDeleteFile`這種"[camelCase](https://en.wikipedia.org/wiki/CamelCase)",如果超過了三個單詞連在一起,其實是很礙眼的東西,所以如果你能用一個單詞表示同樣的意義,那當然更好。 4. 把復雜的邏輯提取出去,做成“幫助函數”。有些人寫的函數很長,以至于看不清楚里面的語句在干什么,所以他們誤以為需要寫注釋。如果你仔細觀察這些代碼,就會發現不清晰的那片代碼,往往可以被提取出去,做成一個函數,然后在原來的地方調用。由于函數有一個名字,這樣你就可以使用有意義的函數名來代替注釋。舉一個例子: ~~~ ... // put elephant1 into fridge2 openDoor(fridge2); if (elephant1.alive()) { ... } else { ... } closeDoor(fridge2); ... ~~~ 如果你把這片代碼提出去定義成一個函數: ~~~ void put(Elephant elephant, Fridge fridge) { openDoor(fridge); if (elephant.alive()) { ... } else { ... } closeDoor(fridge); } ~~~ 這樣原來的代碼就可以改成: ~~~ ... put(elephant1, fridge2); ... ~~~ 更加清晰,而且注釋也沒必要了。 5. 把復雜的表達式提取出去,做成中間變量。有些人聽說“函數式編程”是個好東西,也不理解它的真正含義,就在代碼里使用大量嵌套的函數。像這樣: ~~~ Pizza pizza = makePizza(crust(salt(), butter()), topping(onion(), tomato(), sausage())); ~~~ 這樣的代碼一行太長,而且嵌套太多,不容易看清楚。其實訓練有素的函數式程序員,都知道中間變量的好處,不會盲目的使用嵌套的函數。他們會把這代碼變成這樣: ~~~ Crust crust = crust(salt(), butter()); Topping topping = topping(onion(), tomato(), sausage()); Pizza pizza = makePizza(crust, topping); ~~~ 這樣寫,不但有效地控制了單行代碼的長度,而且由于引入的中間變量具有“意義”,步驟清晰,變得很容易理解。 6. 在合理的地方換行。對于絕大部分的程序語言,代碼的邏輯是和空白字符無關的,所以你可以在幾乎任何地方換行,你也可以不換行。這樣的語言設計,是一個好東西,因為它給了程序員自由控制自己代碼格式的能力。然而,它也引起了一些問題,因為很多人不知道如何合理的換行。 有些人喜歡利用IDE的自動換行機制,編輯之后用一個熱鍵把整個代碼重新格式化一遍,IDE就會自動的把超過行寬限制的代碼自動折行。可是這種自動這行,往往沒有根據代碼的邏輯和讀者的理解來進行。你有可能得到這樣的代碼: ~~~ if (someLongCondition1() && someLongCondition2() && someLongCondition3() && someLongCondition4()) { ... } ~~~ 由于`someLongCondition4()`超過了行寬限制,被編輯器自動換到了下面一行。雖然這樣滿足了行寬限制,可是卻是相當任意的。它并不能幫助人理解這代碼的邏輯。這幾個boolean表達式,全都用`&&`連接,所以它們其實處于平等的地位。為了表達這一點,當這行太長需要折行的時候,你應該把每一個表達式都做成新的一行,就像這個樣子: ~~~ if (someLongCondition1() && someLongCondition2() && someLongCondition3() && someLongCondition4()) { ... } ~~~ 這樣每一個條件都對齊,里面的邏輯就很清楚了。再舉個例子: ~~~ log.info("failed to find file {} for command {}, with exception {}", file, command, exception); ~~~ 這行因為太長,被自動折行成這個樣子。它就不如折成這個樣子: ~~~ log.info("failed to find file {} for command {}, with exception {}", file, command, exception); ~~~ 把格式字符串單獨放在一行,而把它的參數放在另外一樣,這樣邏輯就更加清晰。 為了避免IDE把這些手動調整好的換行弄亂,很多IDE(比如IntelliJ)的自動格式化設定里都有“保留原來的換行符”的設定。如果你發現IDE的換行不符合邏輯,你可以修改這些設定,然后在某些地方保留你自己的手動換行。 說到這里,我必須警告你,這里所說的“不需注釋,讓代碼自己解釋自己”,并不是說要讓代碼看起來像某種自然語言。有個叫Chai的JavaScript測試工具,可以讓你這樣寫代碼: ~~~ expect(foo).to.be.a('string'); expect(foo).to.equal('bar'); expect(foo).to.have.length(3); expect(tea).to.have.property('flavors').with.length(3); ~~~ 這種做法是極其錯誤的。程序語言本來就比自然語言簡單清晰,這種寫法讓它看起來像自然語言的樣子,反而變得復雜難懂了。
                  <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>

                              哎呀哎呀视频在线观看