原文連結: 開始讀 Go 源碼了
學完 Go 的基礎知識已經有一段時間了,那麼接下來應該學什麼呢?有幾個方向可以考慮,比如說 Web 開發,網絡程式設計等。
在下一階段的學習之前,寫了一個開源項目|Go 開發的一款分布式唯一 ID 生成系統,如果你對這個項目感興趣的話,可以在 GitHub 上拿到源碼。
在寫項目的過程中,發現一個問題。實作功能是沒問題的,但不知道自己寫的代碼是不是符合 Go 的風格,是不是夠優雅。是以我覺得相比于繼續學習應用開發,不如向底層前進,打好基礎,打好寫 Go 代碼的基礎。
是以,我決定開始讀 Go 标準庫源碼,Go 一共有 150+ 标準庫,想要全部讀完的話不是不可能,但絕對是一項大工程,希望自己能堅持下去。
為什麼從 Go 标準庫的源碼開始讀呢?因為最近也看了一些 Go 底層原理的書,說實話,像 goroutine 排程,gc 垃圾回收這些内容,根本就看不懂。這要是一上來就讀這部分代碼,恐怕直接就放棄 Go 語言學習了。
而标準庫就不一樣了,有一部分代碼根本不涉及底層原理,實作也相對簡單,同時又能對 Go 的理念加深了解,作為入門再好不過了。然後再由簡入深,循序漸進,就像打怪更新一樣,一步一步征服 Go。
說了這麼多,那到底應該怎麼讀呢?我想到了一些方法:
看官方标準庫文檔。
看網上其他人的技術文章。
寫一些例子來練習如何使用。
如果可以的話,自己實作标準庫的功能。
将自己的閱讀心得總結輸出。
可以通過上面的一種或幾種方法相結合,然後再不斷閱讀不斷總結,最終找到一個完全适合自己的方法。
下面是我總結的一些标準庫及功能介紹:
<code>archive/tar</code> 和 <code>/zip-compress</code>:壓縮(解壓縮)檔案功能。
<code>fmt</code>-<code>io</code>-<code>bufio</code>-<code>path/filepath</code>-<code>flag</code>:
<code>fmt</code>:提供格式化輸入輸出功能。
<code>io</code>:提供基本輸入輸出功能,大多數是圍繞系統功能的封裝。
<code>bufio</code>:緩沖輸入輸出功能的封裝。
<code>path/filepath</code>:用來操作在目前系統中的目标檔案名路徑。
<code>flag</code>:提供對指令行參數的操作。
<code>strings</code>-<code>strconv</code>-<code>unicode</code>-<code>regexp</code>-<code>bytes</code>:
<code>strings</code>:提供對字元串的操作。
<code>strconv</code>:提供将字元串轉換為基礎類型的功能。
<code>unicode</code>:為 unicode 型的字元串提供特殊的功能。
<code>regexp</code>:正規表達式功能。
<code>bytes</code>:提供對字元型分片的操作。
<code>index/suffixarray</code>:子字元串快速查詢。
<code>math</code>-<code>math/cmath</code>-<code>math/big</code>-<code>math/rand-sort</code>:
<code>math</code>:基本的數學函數。
<code>math/cmath</code>:對複數的操作。
<code>math/rand</code>:僞随機數生成。
<code>sort</code>:為數組排序和自定義集合。
<code>math/big</code>:大數的實作和計算。
<code>container</code>-<code>/list</code>-<code>/ring</code>-<code>/heap</code>:
<code>list</code>:雙連結清單。
<code>ring</code>:環形連結清單。
<code>heap</code>:堆。
<code>compress/bzip2</code>-<code>/flate</code>-<code>/gzip</code>-<code>/lzw</code>-<code>zlib</code>:
<code>compress/bzip2</code>:實作 bzip2 的解壓。
<code>flate</code>:實作 deflate 的資料壓縮格式,如 RFC 1951 所述。
<code>gzip</code>:實作 gzip 壓縮檔案的讀寫。
<code>lzw</code>:Lempel Ziv Welch 壓縮資料格式實作。
<code>zlib</code>:實作 zlib 資料壓縮格式的讀寫。
<code>context</code>:用來簡化對于處理單個請求的多個 goroutine 之間與請求域的資料、取消信号、截止時間等相關操作。
<code>crypto</code>-<code>crypto/md5</code>-<code>crypto/sha1</code>:
<code>crypto</code>:常用密碼常數的集合。
<code>crypto/md5</code>:MD5 加密。
<code>crypto/sha1</code>:SHA1 加密。
<code>errors</code>:實作操作出錯的方法。
<code>expvar</code>:為公共變量提供标準化的接口。
<code>hash</code>:所有散列函數實作的通用接口。
<code>html</code>:HTML 文本轉碼轉義功能。
<code>sort</code>:提供用于對切片和使用者定義的集合進行排序的原始函數。
<code>unsafe</code>:包含了一些打破 Go 語言「類型安全」的指令,一般程式不會使用,可用在 C/C++ 程式的調用中。
<code>syscall</code>-<code>os</code>-<code>os/exec</code>:
<code>syscall</code>:提供了作業系統底層調用的基本接口。
<code>os</code>:提供給我們一個平台無關性的作業系統功能接口,采用類 Unix 設計,隐藏了不同作業系統間差異,讓不同的檔案系統和作業系統對象表現一緻。
<code>os/exec</code>:提供了運作外部作業系統指令和程式的方式。
<code>time</code>-<code>log</code>:
<code>time</code>:日期和時間的基本操作。
<code>log</code>:記錄程式運作時産生的日志。
<code>encoding/json</code>-<code>encoding/xml</code>-<code>text/template</code>:
<code>encoding/json</code>:讀取并解碼和寫入并編碼 JSON 資料。
<code>encoding/xml</code>:簡單的 XML1.0 解析器。
<code>text/template</code>:生成像 HTML 一樣的資料與文本混合的資料驅動模闆。
<code>net</code>-<code>net/http</code>:
<code>net</code>:網絡資料的基本操作。
<code>http</code>:提供了一個可擴充的 HTTP 伺服器和基礎用戶端,解析 HTTP 請求和回複。
<code>runtime</code>:Go 程式運作時的互動操作,例如垃圾回收和協程建立。
<code>reflect</code>:實作通過程式運作時反射,讓程式操作任意類型的變量。
這裡僅僅列舉了一部分标準庫,更全面的标準庫清單大家可以直接看官網。
那麼問題來了,這麼多庫從何下手呢?
我這裡做一個簡單的分類,由于水準有限,隻能做一些簡單的梳理,然後大家可以結合自己的實際情況來做選擇。
有些庫涉及到非常專業的知識,投入産出比可能會比較低。比如 <code>archive</code>、<code>compress</code> 以及 <code>crypto</code>,涉及到壓縮算法以及加密算法的知識。
有些庫屬于工具類,比如 <code>bufio</code>、<code>bytes</code>、<code>strings</code>、<code>path</code>、<code>strconv</code> 等,這些庫不涉及領域知識,閱讀起來比較容易。
有些庫屬于與作業系統打交道的,比如 <code>os</code>,<code>net</code>、<code>sync</code> 等,學習這些庫需要對作業系統有明确的認識。
<code>net</code> 下的很多子包與網絡協定相關,比如 <code>net/http</code>,涉及 <code>http</code> 封包的解析,需要對網絡協定比較了解。
如果想要深入了解語言的底層原理,則需要閱讀 <code>runtime</code> 庫。
要想快速入門,并且了解語言的設計理念,建議閱讀 <code>io</code> 以及 <code>fmt</code> 庫,閱讀後會對接口的設計了解更深。
我已經看了一些源碼,雖然過程痛苦,但确實非常有用。前期可能了解起來比較困難,用的時間長一些,但形成固定套路之後,會越來越熟悉,用的時間也會更少,了解也會更深刻。
後續我還會繼續總結輸出,請大家持續關注,讓我們學起來。
開源項目:
https://github.com/yongxinz/id-maker
往期文章:
開源項目|Go 開發的一款分布式唯一 ID 生成系統
測試小姐姐問我 gRPC 怎麼用,我直接把這篇文章甩給了她
gRPC,爆贊