這是一個建立於 的文章,其中的資訊可能已經有所發展或是發生改變。![我在2016年倫敦Golang英國會議上談論代碼縮排線](https://raw.githubusercontent.com/studygolang/gctt-images/master/line-of-sight/1_CBjBs9EzL8q1AL6XvjjpJg.png)在近期倫敦舉行的 [Golang 英國會議](https://www.youtube.com/watch?v=yeetIgNeIkc) 上,我在[地道的Go 語言竅門](https://www.youtube.com/watch?v=yeetIgNeIkc) 交流([投影片](http://go-talks.appspot.com/github.com/matryer/present/idiomatic-go-tricks/main.slide#1))中講到關於代碼中的縮排線, 我想在這裡稍微解釋一下。> 縮排線是“觀察者無障礙視線的直線”![代碼中的縮排線:左圖的縮排是錯誤處理和邊緣情況的快樂路徑](https://raw.githubusercontent.com/studygolang/gctt-images/master/line-of-sight/1_nXXRSHi_1kmgorkcDHyc1Q.png)良好的代碼縮排線不僅對你的功能沒有任何影響,還可以協助其他需要的人閱讀你的代碼。其他程式員(包括你未來的自己)可以瀏覽一個專欄並且理解代碼的預期流程。如果他們不得不在腦子裡分析 `if` 語句,若沒有良好的縮排線,將會使這個任務變得非常艱難。> 大多數人關注編寫代碼的代價(比如“這需要多長時間才能完成?”)但是維護代碼的成本要高得多 - 特別是在成熟的項目中。 讓功能明顯,清晰,簡單易懂才是至關重要的。良好縮排線的建議:* 讓[快樂路徑](https://en.wikipedia.org/wiki/Happy_path)居左側對齊,這樣你就可以快速掃描一列來查看預期的執行流程* 不要隱藏縮排大括弧中代碼邏輯* 儘早的退出 `function`* 避免 `else return`,考慮翻轉 `if` 語句* 把 `return` 聲明作為最後一行* 提取 `function` 和 `method` 以保持結構小巧和可讀* 如果你需要大縮排的代碼,考慮當做一個 `function` 分解出來當然,會有很多很好的理由來打破所有這些規則 - 但是採用這種風格作為預設規則,我們發現我們的代碼變得更具可讀性。## 避免 `else return`編寫具有良好視覺效果的代碼的關鍵是保持 `else` 結構小巧,或者如果可以的話,完全避免它們。 看下這個代碼:```goif something.OK() {something.Lock()defer something.Unlock()err := something.Do()if err == nil {stop := StartTimer()defer stop()log.Println("working...")doWork(something)<-something.Done() // wait for itlog.Println("finished")return nil} else {return err}} else {return errors.New("something not ok")}```這代表了我們最初如何思考我們的功能在做什麼(“如果某件事情沒問題,那麼就做,如果沒有錯誤,那麼做這些事情”等等),但是它變得很難遵循。上面的代碼很難遵循'快樂路徑'(執行順利進行的路線)。它在第二行開始縮排並從那裡繼續。 當我們檢查來自 `something.Do()` 的錯誤返回時,我們進一步縮排。 事實上,語句“ `return nil` ”在代碼中間完全丟失。`else` 結構在 Go 和其他語言中作為單一行返回很常見,因為它們要處理中止或退出函數。 我認為他們不能保證縮排我們的其他代碼。## 翻轉 if 語句如果我們要翻譯 `if` 語句*(如果你喜歡* , *就把它們*翻*過來)* ,你可以看到代碼變得更加可讀:```goif !something.OK() { // flippedreturn errors.New("something not ok")}something.Lock()defer something.Unlock()err := something.Do()if err != nil { // flippedreturn err}stop := StartTimer()defer stop()log.Println("working...")doWork(something)<-something.Done() // wait for itlog.Println("finished")return nil```在此代碼中,我們正在儘早退出,結束代碼與正常代碼不同。而且,* 快樂路徑沿著左側向下保持,* 我們縮排只是為了處理錯誤和邊緣情況,* 我們的 `retutn` 聲明“ `return nil` ”在最後一行,並且,* 我們有更少的縮排代碼塊。## 促進大型條件塊的功能如果你不能避免一個笨重的 `else` 結構或臃腫的選擇切換的情況(我明白了,有時候你不能),那麼就考慮把每個結構分解成它自己的功能:```gofunc processValue(v interface{}) error {switch val := v.(type) {case string:return processString(val)case int:return processInt(val)case bool:return processBool(val)default:return fmt.Errorf("unsupported type %T", v)}}```這比讀取大量的處理代碼更容易閱讀。## 分享你的經驗如果你同意我的觀點,請考慮分享這篇文章 - 隨著越來越多的人註冊,更好的(更一致的)Go 代碼將會出現。你有一些難以閱讀的代碼嗎? 為什麼不在 [Twitter @matryer](https://translate.googleusercontent.com/translate_c?depth=1&hl=zh-CN&prev=search&rurl=translate.google.com.hk&sl=en&sp=nmt4&u=https://twitter.com/matryer&xid=17259,15700023,15700124,15700149,15700168,15700173,15700186,15700201&usg=ALkJrhgR995EkjexZDOQl9LYu8Sl7eq3TA) 上分享它,可以看看我們是否可以找到一個更清潔,更簡單的版本。## 致謝...評論家[戴夫錢尼](https://translate.googleusercontent.com/translate_c?depth=1&hl=zh-CN&prev=search&rurl=translate.google.com.hk&sl=en&sp=nmt4&u=http://dave.cheney.net/&xid=17259,15700023,15700124,15700149,15700168,15700173,15700186,15700201&usg=ALkJrhgTC1jmfDNNabAZ1iX8dJSOjyuddw) , [大衛埃爾南德斯](https://translate.googleusercontent.com/translate_c?depth=1&hl=zh-CN&prev=search&rurl=translate.google.com.hk&sl=en&sp=nmt4&u=http://twitter.com/dahernan&xid=17259,15700023,15700124,15700149,15700168,15700173,15700186,15700201&usg=ALkJrhhm04bLuew6j4VCw3ACIxtPeMMmxA)和[威廉甘迺迪](https://translate.googleusercontent.com/translate_c?depth=1&hl=zh-CN&prev=search&rurl=translate.google.com.hk&sl=en&sp=nmt4&u=https://twitter.com/goinggodotnet&xid=17259,15700023,15700124,15700149,15700168,15700173,15700186,15700201&usg=ALkJrhi57B943koWpS6pe4_aRslBMy-7mw) 。
via: https://medium.com/@matryer/line-of-sight-in-code-186dd7cdea88
作者:Mat Ryer 譯者:yuhanle 校對:polaris1119
本文由 GCTT 原創編譯,Go語言中文網 榮譽推出
本文由 GCTT 原創翻譯,Go語言中文網 首發。也想加入譯者行列,為開源做一些自己的貢獻嗎?歡迎加入 GCTT!
翻譯工作和譯文發表僅用於學習和交流目的,翻譯工作遵照 CC-BY-NC-SA 協議規定,如果我們的工作有侵犯到您的權益,請及時聯絡我們。
歡迎遵照 CC-BY-NC-SA 協議規定 轉載,敬請在本文中標註並保留原文/譯文連結和作者/譯者等資訊。
文章僅代表作者的知識和看法,如有不同觀點,請樓下排隊吐槽
419 次點擊