推薦序
前言
第一部分 熟知Go語言的一切
第1條 瞭解Go語言的誕生與演進2
1.1 Go語言的誕生2
1.2 Go語言的早期團隊和演進曆程4
1.3 Go語言正式發布並開源4
第2條 選擇適當的Go語言版本6
2.1 Go語言的先祖6
2.2 Go語言的版本發布曆史7
2.3 Go語言的版本選擇建議11
第3條 理解Go語言的設計哲學12
3.1 追求簡單,少即是多12
3.2 偏好組閤,正交解耦15
3.3 原生並發,輕量高效17
3.4 麵嚮工程,“自帶電池”21
第4條 使用Go語言原生編程思維來寫Go代碼26
4.1 語言與思維—來自大師的觀點26
4.2 現實中的“投影”27
4.3 Go語言原生編程思維29
第二部分 項目結構、代碼風格與標識符命名
第5條 使用得到公認且廣泛使用的項目結構32
5.1 Go項目的項目結構32
5.2 Go語言典型項目結構35
第6條 提交前使用gofmt格式化源碼40
6.1 gofmt:Go語言在解決規模化問題上的最佳實踐40
6.2 使用gofmt41
6.3 使用goimports43
6.4 將gofmt/goimports與IDE或編輯器工具集成44
第7條 使用Go命名慣例對標識符進行命名47
7.1 簡單且一緻48
7.2 利用上下文環境,讓最短的名字攜帶足夠多的信息53
第三部分 聲明、類型、語句與
控製結構
第8條 使用一緻的變量聲明形式56
8.1 包級變量的聲明形式56
8.2 局部變量的聲明形式59
第9條 使用無類型常量簡化代碼63
9.1 Go常量溯源63
9.2 有類型常量帶來的煩惱64
9.3 無類型常量消除煩惱,簡化代碼65
第10條 使用iota實現枚舉常量68
第11條 盡量定義零值可用的類型73
11.1 Go類型的零值73
11.2 零值可用75
第12條 使用復閤字麵值作為初值構造器78
12.1 結構體復閤字麵值79
12.2 數組/切片復閤字麵值80
12.3 map復閤字麵值81
第13條 瞭解切片實現原理並高效使用83
13.1 切片究竟是什麼83
13.2 切片的高級特性:動態擴容87
13.3 盡量使用cap參數創建切片90
第14條 瞭解map實現原理並高效使用92
14.1 什麼是map92
14.2 map的基本操作93
14.3 map的內部實現97
14.4 盡量使用cap參數創建map103
第15條 瞭解string實現原理並高效使用105
15.1 Go語言的字符串類型105
15.2 字符串的內部錶示110
15.3 字符串的高效構造112
15.4 字符串相關的高效轉換115
第16條 理解Go語言的包導入120
16.1 Go程序構建過程121
16.2 究竟是路徑名還是包名127
16.3 包名衝突問題130
第17條 理解Go語言錶達式的求值順序132
17.1 包級彆變量聲明語句中的錶達式求值順序133
17.2 普通求值順序136
17.3 賦值語句的求值139
17.4 switch/select語句中的錶達式求值140
第18條 理解Go語言代碼塊與作用域143
18.1 Go代碼塊與作用域簡介143
18.2 if條件控製語句的代碼塊145
18.3 其他控製語句的代碼塊規則簡介148
第19條 瞭解Go語言控製語句慣用法及使用注意事項154
19.1 使用if控製語句時應遵循“快樂路徑”原則154
19.2 for range的避“坑”指南156
19.3 break跳到哪裏去瞭165
19.4 盡量用case錶達式列錶替代fallthrough167
第四部分 函數與方法
第20條 在init函數中檢查包級變量的初始狀態170
20.1 認識init函數170
20.2 程序初始化順序171
20.3 使用init函數檢查包級變量的初始狀態174
第21條 讓自己習慣於函數是“一等公民”179
21.1 什麼是“一等公民”179
21.2 函數作為“一等公民”的特殊運用183
第22條 使用defer讓函數更簡潔、更健壯192
22.1 defer的運作機製193
22.2 defer的常見用法194
22.3 關於defer的幾個關鍵問題199
第23條 理解方法的本質以選擇
正確的receiver類型206
23.1 方法的本質207
23.2 選擇正確的receiver類型208
23.3 基於對Go方法本質的理解巧解難題210
第24條 方法集閤決定接口實現214
24.1 方法集閤215
24.2 類型嵌入與方法集閤216
24.3 defined類型的方法集閤226
24.4 類型彆名的方法集閤227
第25條 瞭解變長參數函數的妙用230
25.1 什麼是變長參數函數230
25.2 模擬函數重載233
25.3 模擬實現函數的可選參數與默認參數236
25.4 實現功能選項模式238
第五部分 接口
第26條 瞭解接口類型變量的內部錶示246
26.1 nil error值 != nil247
26.2 接口類型變量的內部錶示248
26.3 輸齣接口類型變量內部錶示的詳細信息254
26.4 接口類型的裝箱原理258
第27條 盡量定義小接口263
27.1 Go推薦定義小接口263
27.2 小接口的優勢265
27.3 定義小接口可以遵循的一些點267
第28條 盡量避免使用空接口作為函數參數類型270
第29條 使用接口作為程序水平組閤的連接點274
29.1 一切皆組閤274
29.2 垂直組閤迴顧275
29.3 以接口為連接點的水平組閤276
第30條 使用接口提高代碼的可測試性281
30.1 實現一個附加免責聲明的電子郵件發送函數282
30.2 使用接口來降低耦閤283
第六部分 並發編程
第31條 優先考慮並發設計288
31.1 並發與並行288
31.2 Go並發設計實例290
第32條 瞭解goroutine的調度原理299
32.1 goroutine調度器299
32.2 goroutine調度模型與演進過程300
32.3 對goroutine調度器原理的進一步理解302
32.4 調度器狀態的查看方法305
32.5 goroutine調度實例簡要分析307
第33條 掌握Go並發模型和常見並發模式315
33.1 Go並發模型315
33.2 Go常見的並發模式317
第34條 瞭解channel的妙用340
34.1 無緩衝channel341
34.2 帶緩衝channel347
34.3 nil channel的妙用354
34.4 與select結閤使用的一些慣用法357
第35條 瞭解sync包的正確用法359
35.1 sync包還是channel359
35.2 使用sync包的注意事項360
35.3 互斥鎖還是讀寫鎖362
35.4 條件變量365
35.5 使用sync.Once實現單例模式 368
35.6 使用sync.Pool減輕垃圾迴收壓力370
第36條 使用atomic包實現伸縮性更好的並發讀取374
36.1 atomic包與原子操作374
36.2 對共享整型變量的無鎖讀寫375
36.3 對共享自定義類型變量的無鎖讀寫377
第七部分 錯誤處理
第37條 瞭解錯誤處理的4種策略382
37.1 構造錯誤值383
37.2 透明錯誤處理策略385
37.3 “哨兵”錯誤處理策略385
37.4 錯誤值類型檢視策略388
37.5 錯誤行為特徵檢視策略390
第38條 盡量優化反復齣現的if err != nil392
38.1 兩種觀點393
38.2 盡量優化395
38.3 優化思路395
第39條 不要使用panic進行正常的錯誤處理405
39.1 Go的panic不是Java的checked exception405
39.2 panic的典型應用408
39.3 理解panic的輸齣信息412
(以上為本書內容,以下為第2冊內容。)
第八部分 測試、性能剖析與調試
第40條 理解包內測試與包外測試的差彆
40.1 官方文檔的“自相矛盾”
40.2 包內測試與包外測試
第41條 有層次地組織測試代碼
· · · · · · (
收起)