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

浙公網安備 33010602011771號