<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          喜歡寫(xiě)注釋嗎?喜歡寫(xiě),你就輸了

          共 4322字,需瀏覽 9分鐘

           ·

          2020-08-27 09:36

          關(guān)注?W3Cschool?,每天一篇文章,與你共同成長(zhǎng)

          作者丨Tameem Iftikhar

          翻譯丨平川

          策劃丨Tina


          我并不是提倡不寫(xiě)代碼注釋,只是建議不要過(guò)于依賴注釋,這樣可以使代碼更干凈、更有表現(xiàn)力,這也能提高開(kāi)發(fā)人員的水平。我自己也在尋求編寫(xiě)更簡(jiǎn)潔的代碼,我盡力不編寫(xiě)糟糕的注釋,并在可能時(shí)重構(gòu)代碼。

          這篇文章的標(biāo)題可能會(huì)讓你情緒激動(dòng),但請(qǐng)先耐心聽(tīng)我說(shuō)完。在適當(dāng)?shù)奈恢脤?xiě)下適當(dāng)?shù)淖⑨尶赡芊浅S杏?,但是沒(méi)有什么比無(wú)用的注釋更讓代碼混亂了。在某些情況下,我敢說(shuō),注釋可以彌補(bǔ)我們?cè)诖a中沒(méi)有完全表達(dá)出來(lái)的意思。因此,寫(xiě)注釋不值得贊美,而是應(yīng)該停下來(lái)問(wèn)問(wèn)自己,是否有更好的方式可以用代碼來(lái)表達(dá)自己。

          帶有少量注釋的清晰而富于表現(xiàn)力的代碼,要比帶有大量注釋的混亂而復(fù)雜的代碼好得多。如果你已經(jīng)把代碼弄得一團(tuán)糟,不要花時(shí)間寫(xiě)注釋來(lái)解釋,而是要花時(shí)間梳理代碼。如果每次寫(xiě)注釋的時(shí)候,你都冥思苦想,覺(jué)得自己的表達(dá)能力不足,那么最終你就會(huì)寫(xiě)出簡(jiǎn)潔明了的代碼,完全沒(méi)有必要寫(xiě)注釋。鼓勵(lì)自己用代碼表達(dá)。

          為什么對(duì)注釋如此不屑?

          因?yàn)樗鼈儠?huì)說(shuō)謊,還會(huì)把代碼弄得亂七八糟。雖說(shuō)并非總是如此,也并非有意如此,但卻經(jīng)常如此。糟糕的代碼和帶有大量注釋的代碼之間有很高的相關(guān)性。注釋存在的時(shí)間越久就越容易偏離它們所描述的代碼——在某些情況下,它們可能是完全錯(cuò)誤的。實(shí)際上,隨著代碼庫(kù)和團(tuán)隊(duì)的增長(zhǎng),維護(hù)注釋成了不可能的事情。

          注釋不同于《辛德勒的名單》。它們不是“純善的”。事實(shí)上,注釋充其量是一種必要的惡?!猂obert C.Martin

          當(dāng)談?wù)撽P(guān)于注釋的話題時(shí),很重要的一點(diǎn)是,我們要看一下什么是恰當(dāng)?shù)淖⑨?,什么是糟糕的注釋,這樣我們才能學(xué)會(huì)寫(xiě)更好的注釋,或者完全避免注釋。

          恰當(dāng)?shù)淖⑨?/span>

          并不是所有的注釋都是不好的——有些注釋實(shí)際上非常必要。

          出于法律目的的注釋

          有時(shí)候,你可能需要出于法律目的編寫(xiě)特定的注釋,比如開(kāi)源項(xiàng)目的創(chuàng)作許可。一些現(xiàn)代化的 IDE 和文本編輯器會(huì)自動(dòng)將它們折疊起來(lái),保持工作區(qū)的整潔。

          魔術(shù)表達(dá)式

          如果你有一個(gè)復(fù)雜的 SQL 或正則表達(dá)式,它以神奇的方式做了一些令人興奮的事,那么請(qǐng)務(wù)必注釋,以便讓讀者更容易理解,因?yàn)槲覀兌疾皇?Regex 忍者。

          //?匹配電子郵件地址的正則表達(dá)式
          var?re?=?/^(([^<>()\[\]\\.,;:\s@"]+(\.[^<>()\[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/;
          return?re.test(String(email).toLowerCase());
          //?注意:添加一個(gè)富于表現(xiàn)力的函數(shù)名,注釋就變得沒(méi)有必要了
          function?validateEmail(email)?{
          ????var?re?=?/^(([^<>()\[\]\\.,;:\s@"]+(\.[^<>()\[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/;
          ????return?re.test(String(email).toLowerCase());
          }

          說(shuō)明意圖

          在某些情況下,注釋有助于解釋決策或特定解決方案背后的意圖。例如,測(cè)試套件中的一條注釋告訴我們添加這行代碼是為了降低死鎖的幾率。


          for?x?in?range(1,?500):

          ??#?這是運(yùn)行多個(gè)并行測(cè)試時(shí)預(yù)防死鎖的最好方法
          ??time.sleep(0.5)
          ??runTest(x)
          ??

          結(jié)果預(yù)警

          用注釋說(shuō)明代碼可能會(huì)產(chǎn)生嚴(yán)重的或可怕的后果,甚至鼓勵(lì)這樣做。在本例中,開(kāi)發(fā)人員讓讀者知道,當(dāng)與回調(diào)函數(shù)一起使用時(shí),QT 函數(shù)不是線程安全的。一般來(lái)說(shuō),如果一條注釋可以避免某個(gè)人在編程時(shí)陷入絕望,那么它就是有用的。

          """
          ??許多 Qt 函數(shù)都不是線程安全的。如果你使用回調(diào)函數(shù),
          ??即使你在所有繪制調(diào)用代碼的周?chē)技由湘i,你也會(huì)遇到段錯(cuò)誤,
          ??因?yàn)?Qt 的主事件循環(huán)仍在運(yùn)行,并且使用了沒(méi)加鎖的資源。
          "
          ""
          from?multiprocessing.pool?import?ThreadPool
          import?sys
          from?threading?import?Lock
          import?time
          from?PyQt5?import?QtCore,?QtWidgets
          class?Task(QtCore.QObject):
          ????updated?=?QtCore.pyqtSignal(int,?int)
          ????...............
          ????...............
          ????

          TODO 注釋

          這些注釋可以幫助我們標(biāo)記那些我們認(rèn)為應(yīng)該做,但是由于某些原因沒(méi)有做到的事情。它可能會(huì)提醒你刪除廢棄的特性,或者請(qǐng)求其他人查看某個(gè)問(wèn)題。它可能是要求其他人想一個(gè)更好的名字,或者是提醒他們根據(jù)計(jì)劃事件做出修改。

          請(qǐng)記住,TODO 注釋不是在系統(tǒng)中留下糟糕代碼的借口。本質(zhì)上,每一行代碼都是一種負(fù)擔(dān)——最安全、最快的代碼是根本沒(méi)有代碼。

          現(xiàn)在,大多數(shù)優(yōu)秀的 IDE 都提供了特殊的指令和特性來(lái)定位所有的 TODO 注釋,所以不太可能漏掉它們。盡管如此,你也不希望代碼中到處都是 TODO。所以要經(jīng)常瀏覽一下,刪除那些你能刪除的。

          糟糕的注釋

          這個(gè)清單比較長(zhǎng),但在本節(jié)中,我們將看到一些更為老生常談而又隨處可見(jiàn)的注釋。

          明知故問(wèn)的注釋

          有些注釋的意思顯而易見(jiàn),即它們沒(méi)有增加任何實(shí)際的價(jià)值,而且大多是噪音。

          下面是一個(gè)開(kāi)源項(xiàng)目的代碼片段,其中包含大量明知故問(wèn)型的注釋,這些注釋使代碼變得混亂而晦澀。它們所提供的信息并不比代碼本身多,而且在某些情況下,閱讀注釋的時(shí)間甚至比閱讀代碼長(zhǎng)。


          /**
          *?與該容器相關(guān)的集群
          */
          protected?Cluster?cluster?=?null;
          /**
          *?人類可讀的容器名
          */
          protected?String?name?=?null;
          /**
          *?該容器的父容器
          */
          protected?Container?parent?=?null;
          /**
          *?創(chuàng)建一個(gè)?Loader?配置父類加載器
          */
          protected?ClassLoader?parentClassLoader?=?null;

          不清不楚的注釋

          如果你寫(xiě)注釋是為了符合公司規(guī)定,或者你只是覺(jué)得有必要添加一些注釋,那么你在注釋時(shí)就不會(huì)進(jìn)行適當(dāng)?shù)乃伎?。所以,如果你真的?xiě)了一條注釋,花點(diǎn)時(shí)間讓它對(duì)閱讀它的人有所幫助。


          def?load_config():
          ??try:
          ????do_useful_stuff()
          ??except?Exception?as?ex:
          ????#?如有異常,退回到默認(rèn)狀態(tài)。

          在這個(gè)例子中,作者想要傳達(dá)一些有關(guān)異常情況的重要信息。但這條注釋沒(méi)能解釋清楚我們將退回到什么樣的默認(rèn)狀態(tài)。如果一條注釋要求我們轉(zhuǎn)到另一個(gè)模塊來(lái)找出默認(rèn)值,那么它就沒(méi)有發(fā)揮應(yīng)有的作用。

          注釋掉代碼

          在團(tuán)隊(duì)準(zhǔn)備好刪除代碼之前先將其注釋掉似乎是一個(gè)好主意,但是不要這樣做。注釋代碼是一種弊端,團(tuán)隊(duì)中的其他成員不會(huì)刪除它,因?yàn)樗麄儠?huì)認(rèn)為它很重要。我們不是都在使用源碼控制嗎?所以我們不需要保留舊的代碼。我們可以跳到任何我們想要的版本。

          噪音注釋

          有些注釋毫無(wú)意義,純粹是噪音。時(shí)間久了,我們的大腦就會(huì)走馬觀花,我們也會(huì)開(kāi)始跳過(guò)那些需要注意的重要注釋??紤]一下下面的例子,其中的注釋提供了很多價(jià)值嗎?


          -----------------------------
          #?Exhibit?A
          #?默認(rèn)構(gòu)造函數(shù)
          def?get_todays_date():
          ??return?date.today()
          -----------------------------
          #?Exhibit?B
          #?返回月份的天
          #?@return:?月份的天
          def?get_day_of_month()
          ??return?day_of_month

          用編寫(xiě)干凈代碼的決心取代制造噪音的誘惑,你將成為一個(gè)更好、更快樂(lè)的程序員。

          強(qiáng)制性注釋

          這肯定會(huì)引起爭(zhēng)議。如果規(guī)定每個(gè)函數(shù)都需要一個(gè) Java 文檔或 Python docstring,是不是有點(diǎn)傻?大多數(shù)時(shí)候,類或函數(shù)名已經(jīng)告訴我們注釋所描述的內(nèi)容,它們是多余的。在這個(gè)例子中,注釋的數(shù)量比代碼的數(shù)量還多——這讓我很惱火。


          class?ComplexNumber:
          ????"""
          ????這是一個(gè)用于復(fù)數(shù)的數(shù)學(xué)運(yùn)算類。

          ????屬性:
          ??????? real (int):復(fù)數(shù)的實(shí)部。
          ??????? imag (int):復(fù)數(shù)的虛部。
          ????"
          ""

          ????def?__init__(self,?real,?imag):
          ????????"""
          ??????? ComplexNumber 類的構(gòu)造函數(shù)。

          ????????參數(shù):
          ?????????? real (int):復(fù)數(shù)的實(shí)部。
          ?????????? imag (int):復(fù)數(shù)的虛部。
          ????????"
          ""

          ????def?add(self,?num):
          ????????"""
          ????????該函數(shù)用于復(fù)數(shù)求和。

          ????????參數(shù):
          ??????????? num (ComplexNumber):要加的復(fù)數(shù)。

          ????????返回值:
          ??????????? ComplexNumber:包含和的復(fù)數(shù)。
          ????????"
          ""

          ????????re?=?self.real?+?num.real
          ????????im?=?self.imag?+?num.imag

          ????????return?ComplexNumber(re,?im)

          help(ComplexNumber)??#?訪問(wèn)類的?docstring
          help(ComplexNumber.add)??#?訪問(wèn)方法的?docstring

          使用好的函數(shù)名或變量名

          你可以使用更具表達(dá)性的函數(shù)和變量名替換注釋,從而使代碼更簡(jiǎn)潔??紤]下面的例子,第一個(gè)例子中的注釋就變得沒(méi)有必要了,因?yàn)橛幸粋€(gè)更好的函數(shù)名可以準(zhǔn)確地告訴讀者這個(gè)函數(shù)做了什么。


          #?檢查日期是否是過(guò)去的日期
          def?check_date(date):
          ???if?date??????return?true
          ???return?false

          def?is_past_date(date):
          ???if?date??????return?true
          ???return?false
          ???

          注釋不能彌補(bǔ)代碼的糟糕

          編寫(xiě)注釋有一個(gè)比較常見(jiàn)的原因是糟糕的代碼。我們以前都見(jiàn)過(guò)這種情況,在某種程度上,我們自己也犯過(guò)這樣的錯(cuò)誤。我們寫(xiě)一個(gè)模塊或類,我們心里知道它混亂而無(wú)序。我們知道它一團(tuán)糟。所以我們對(duì)自己說(shuō),“哦,我最好加下注釋!”不!你最好把代碼梳理清楚!


          /*
          這段代碼糟透了。我知道,你知道,每個(gè)人都知道。
          我們假裝什么都沒(méi)發(fā)生,然后繼續(xù)前進(jìn)。以后你叫我白癡好了。
          */

          小 ? ?結(jié)

          我并不是提倡不寫(xiě)代碼注釋,只是建議不要過(guò)于依賴注釋,這樣可以使代碼更干凈、更有表現(xiàn)力,這也能提高開(kāi)發(fā)人員的水平。我自己也在尋求編寫(xiě)更簡(jiǎn)潔的代碼,我盡力不編寫(xiě)糟糕的注釋,并在可能時(shí)重構(gòu)代碼——將我的代碼從宜家的一幅畫(huà)變成梵高的作品。

          所以讓我們約法三章,不要寫(xiě)這么多注釋。

          延伸閱讀:

          https://levelup.gitconnected.com/every-time-you-comment-code-youve-already-failed-6fa9773b080f



          -End-


          W3Cschool注冊(cè)會(huì)員突破200萬(wàn)啦~


          編程獅(W3Cschool


          學(xué)編程,從W3Cschool開(kāi)始

          微信掃描二維碼,關(guān)注公眾號(hào)

          點(diǎn)擊分享」「」「在看
          說(shuō)不定你的朋友也喜歡讀▼▼▼
          瀏覽 36
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          評(píng)論
          圖片
          表情
          推薦
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  青青草偷窥美女屄 | 一级电影毛片 | 精品人兽 | 国产又粗又大操逼视频 | 精品欧美一区二区三区成人片 |