原文鏈接: 開始讀 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
庫,閱讀后會對接口的設計理解更深。
我已經看了一些源碼,雖然過程痛苦,但確實非常有用。前期可能理解起來比較困難,用的時間長一些,但形成固定套路之后,會越來越熟悉,用的時間也會更少,理解也會更深刻。
后續我還會繼續總結輸出,請大家持續關注,讓我們學起來。
開源項目:
往期文章: