Go語言從入門到進階實戰

Go語言從入門到進階實戰

本書分為13章,主要介紹了Go語言的特性與環境搭建、基本語法與使用、容器(存儲和組織數據的方式)、流程控制、函式、結構體、接口(interface)、包(package)、並發、反射、編譯與工具、開發技巧,最後的實戰演練部分剖析了作者的開源網路庫cellnet的架構及設計思想,並且實現了Socket聊天功能。本書對於Go語言的特色功能並發有全面、深入的講解,需要讀者重點學習。

書籍介紹

內容簡介

本書採用“理論+實例”的形式編寫,通過大量的實例,結合作者多年的一線開發實戰經驗,全面介紹了Go語言的語法及使用方法。全書秉承方便學習,易於理解,便於查詢的理念,無論是想系統學習Go語言基礎知識的初學者,還是想進階提高的有經驗的開發人員,都能通過本書迅速掌握Go語言的各種基礎語法和開發技巧。本書作者曾經與慕課網合作錄製相關的視頻課程,擁有豐富的視頻製作經驗,所以特意為本書精心錄製了詳細的配套教學視頻,這將極大地提升讀者的學習效率,取得更好的學習效果。另外,本書還免費提供了書中所有實例源程式,為讀者的學習提供便利。

配套學習資源

1.同步配套教學視頻,作者為本書每一章精選了一些例子錄製成同步教學視頻。

2.書中實例的源檔案。

本書提供書中講解到的重要代碼的原始碼,讀者可以邊看視頻邊參考提供的代碼,自己動手實現書中的例子,這樣能迅速理解每個Go語言的語法特性,也能迅速提高編程能力。

本書特色

1. 配套教學視頻

為了讓讀者更好地學習本書,作者給每一章內容都錄製了教學視頻,藉助這些視頻 ,讀者可以更輕鬆地學習。

作者曾接受過慕課網的專業視頻製作指導,並在慕課網做過多期的Go語言、Unity3D遊戲引擎和Cocos遊戲引擎課程,希望讀者能夠通過這些視頻輕鬆地學習Go語言。

2. 來自一線的開發經驗及實際例子

本書的大多數代碼及例子都是來自作者多年的口頭教學、技術分享會等。同時作者本人也是一名開源愛好者,編寫了業內熟知的cellnet網路庫,本書將為讀者介紹cellnet的架構和設計思想,幫助讀者剖析cellnet內部的運行機制,讓讀者能方便地使用cellnet實現業務邏輯。

3. 淺顯易懂的語言、觸類旁通的對比、循序漸進的知識體系

本書在文字及目錄編排上,儘量做到通俗易懂。在講解一些常見語言特性時,將Go語言和多種語言的特性做對比,掌握多種程式語言的開發者能迅速理解Go語言的特性。無論是初學者還是老程式設計師,都能通過本書學習到Go語言的精華之處。

4. 內容全面,實用性強

本書精心挑選了多個實用性很強的例子,例如:JSON串列化、有限狀態機(FSM)、TCP粘包處理、Echo伺服器、事件系統。讀者既可以從這些例子中學習並理解Go語言的知識點,還可以將這些例子用於開發中。

本書精華

Go語法詳細解析

附送100分鐘的視頻教程

72個隨書的原始碼例子

避坑的技巧

作者多年的Go項目實戰經驗

開源網路庫cellnet深入剖析

目錄

配套學習資源

前言

第1章 初識Go語言

1.1 Go語言特性

1.2 使用Go的開源項目

1.3 學會安裝Go

1.3.1 Windows版安裝

1.3.2 Linux版安裝

1.4 搭建開發環境

1.4.1 集成開發環境Jetbrains Goland

1.4.2 方便定義功能的編輯器Visual Studio Code

第2章 基本語法與使用

2.1 變數

2.1.1 聲明變數

2.1.2 初始化變數

2.1.3 多個變數同時賦值

2.1.4 匿名變數 ——沒有名字的變數

2.2 類型

2.2.1 整型

2.2.2 浮點——小數點

2.2.3 示例:輸出正弦(sin)圖像

2.2.4 布爾——是或否

2.2.5 字元串

2.2.6 字元

2.2.7 切片——能動態分配的空間

2.3 轉換不同的數據類型

2.4 指針

2.4.1 認識指針地址和指針類型

2.4.2 從指針獲取指針指向的值

2.4.3 使用指針修改值

2.4.4 示例:使用指針變數獲取命令行的輸入信息

2.4.5 創建指針的另一種方法——new函式

2.5 變數生命期

2.5.1 什麼是棧?

2.5.2 什麼是堆?

2.5.3 變數逃逸分析(Escape Analysis)——自動決定變數分配位置,提高運行效率

2.6 字元串套用

2.6.1 計算字元串長度

2.6.2 遍歷字元串——獲取每一個字元串元素

2.6.3 獲取字元串的某一段字元

2.6.4 修改字元串

2.6.5 連線字元串

2.6.6 格式化字元串——按照指定格式生成字元串

2.6.7 示例:Base64編碼——電子郵件的基礎編碼格式

2.6.8 示例:從INI配置檔案中查詢需要的值

2.7 常量——恆定不會改變的值

2.7.2 枚舉——一組常量值

2.7.3 將枚舉值轉換為字元串

2.8 類型別名(Type Alias)

2.8.1 區分類型別名與類型定義

2.8.2 非本地類型不能定義方法

2.8.3 在結構體成員嵌入時使用別名

第3章 容器:存儲和組織數據的方式

3.1 數組——固定大小的連續空間

3.1.1 聲明數組

3.1.2 初始化數組

3.1.3 遍歷數組——訪問每一個數組元素

3.2 切片(slice)——動態分配大小的連續空間

3.2.1 從數組或切片生成新的切片

3.2.2 聲明切片

3.2.3 使用make構造切片

3.2.4 使用append為切片添加元素

3.2.5 複製切片元素到另一個切片

3.2.6 從切片中刪除元素

3.3 映射(map)——建立事物關聯的容器

3.3.1 添加關聯到map並訪問關聯和數據

3.3.3 遍歷map的“鍵值對”——訪問每一個map中的關聯關係

3.3.4 從map中刪除鍵值對(delete)

3.3.5 清空map中的所有元素

3.3.6 能夠在並發環境中使用的map——sync.Map

3.4 列表(list)——可以快速增刪的非連續空間的容器

3.4.1 初始化列表

3.4.2 在列表中插入元素

3.4.3 從列表中刪除元素

3.4.4 遍歷列表——訪問列表的每一個元素

第4章 流程控制

4.2 構建循環(for)

4.2.1 for中的初始語句——開始循環時執行的語句

4.2.2 for中的條件表達式——控制是否循環的開關

4.2.3 for中的結束語句——每次循環結束時執行的語句

4.3 示例: 九九乘法表

4.4 鍵值循環(for range)——直接獲得對象的索引和數據

4.4.1 遍歷數組、切片——獲得索引和元素

4.4.2 遍歷字元串——獲得字元

4.4.3 遍歷map——獲得map的鍵和值

4.4.4 遍歷通道(channel)——接收通道數據

4.4.5 在遍歷中選擇希望獲得的變數

4.5 分支選擇(switch)——擁有多個條件分支的判斷

4.5.1 基本寫法

4.5.2 跨越case的fallthrough——兼容C語言的case設計

4.6 跳轉到指定代碼標籤(goto)

4.6.1 使用goto退出多層循環

4.6.2 使用goto集中處理錯誤

4.7 跳出指定循環(break)——可以跳出多層循環

4.8 繼續下一次循環(continue)

第5章 函式(function)

5.1 聲明函式

5.1.1 普通函式的聲明形式

5.1.2 參數類型的簡寫

5.1.3 函式的返回值

5.1.4 調用函式

5.1.5 示例:將“秒”解析為時間單位

5.1.6 示例:函式中的參數傳遞效果測試

5.2 函式變數——把函式作為值保存到變數

5.3 示例:字元串的鏈式處理——操作與數據分離的設計技巧

5.4 匿名函式——沒有函式名字的函式

5.4.1 定義一個匿名函式

5.4.1 匿名函式用作回調函式

5.4.2 使用匿名函式實現操作封裝

5.5 函式類型實現接口——把函式當做接口調用

5.5.1 結構體實現接口

5.5.2 函式體實現接口

5.5.3 http包中的例子

5.6 閉包(Closure)——引用了外部變數的匿名函式

5.6.1 在閉包內部修改引用的變數

5.6.2 示例:閉包的記憶效應

5.6.3 示例:閉包實現生成器

5.7 可變參數——參數數量不固定的函式形式

5.7.1 fmt包中的例子

5.7.1 遍歷可變參數列表——獲取每一個參數的值

5.7.2 獲得可變參數類型——獲得每一個參數的類型

5.7.3 在多個可變參數函式中傳遞參數

5.8 延遲執行語句(defer)

5.8.1 多個延遲執行語句的處理順序

5.8.1 使用延遲執行語句在函式退出時釋放資源

5.9 處理運行時發生的錯誤

5.9.1 net包中例子

5.9.1 錯誤接口的定義格式

5.9.2 自定義一個錯誤

5.9.3 示例:在解析中使用自定義錯誤

5.10 宕機(panic)——程式終止運行

5.10.1 手動觸發宕機

5.10.2 在運行依賴的必備資源缺失時主動觸發宕機

5.10.3 在宕機時觸發延遲執行語句

5.11 宕機恢復(recover)——防止程式崩潰

5.11.1 讓程式在崩潰時繼續執行

5.11.2 panic和recover的關係

第6章 結構體(struct)

6.1 定義結構體

6.2 實例化結構體——為結構體分配記憶體並初始化

6.2.1 基本的實例化形式

6.2.2 創建指針類型的結構體

6.2.3 取結構體的地址實例化

6.3 初始化結構體的成員變數

6.3.1 使用“鍵值對”初始化結構體

6.3.2 使用多個值的列表初始化結構體

6.3.3 初始化匿名結構體

6.4 構造函式——結構體和類型的一系列初始化操作的函式封裝

6.4.1 多種方式創建和初始化結構體——模擬構造函式重載

6.4.2 帶有父子關係的結構體的構造和初始化——模擬父級構造調用

6.5 方法

6.5.1 為結構體添加方法

6.5.2 接收器——方法作用的目標

6.5.3 示例:使用二維矢量模擬玩家移動

6.5.4 為類型添加方法

6.5.5 示例:使用事件系統實現事件的回響和處理

6.6 結構體內嵌

6.6.1 聲明結構體內嵌和內嵌的特性

6.6.2 使用組合思想描述對象特性

6.6.3 初始化結構體內嵌

6.6.4 初始化內嵌匿名結構體

6.6.6 成員名字衝突

6.7 示例:使用匿名結構體分離JSON數據

第7章 接口(interface)

7.1 聲明接口

7.1.1 接口聲明的格式

7.1.2 開發中常見的接口及寫法

7.1 實現接口的條件

7.1.1 接口被實現的條件一:接口的方法與實現接口的類型方法格式一致

7.1.2 條件二:接口中所有方法均被實現

7.2 理解類型與接口的關係

7.2.1 一個類型可以實現多個接口

7.2.2 多個類型可以實現相同的接口

7.3 示例:便於擴展輸出方式的日誌系統

7.4 示例:使用接口進行數據的排序

7.4.1 使用sort.Interface接口進行排序

7.4.2 常見類型的便捷排序

7.4.3 對結構體數據進行排序

7.5 接口的嵌套組合 ——將多個接口放在一個接口內

7.6 在接口和類型間轉換

7.6.1 類型斷言的格式

7.6.2 將接口轉換為其他接口

7.6.3 將接口轉換為其他類型

7.7 空接口類型(interface{})——能保存所有值的類型

7.7.1 將值保存到空接口

7.7.2 從空接口獲取值

7.7.3 空接口間的值比較

7.8 示例:使用空接口實現可以保存任意值的字典

7.9 類型分支——批量判斷空接口中變數的類型

7.9.1 類型斷言的書寫格式

7.9.2 使用類型分支判斷基本類型

7.9.3 使用類型分支判斷接口類型

7.10 示例:實現有限狀態機(FSM)

第8章 包(package)

8.1 工作目錄(GOPATH)

8.1.1 使用命令行查看GOPATH信息

8.1.2 使用GOPATH的工程結構

8.1.2 設定和使用GOPATH

8.1.3 在多項目工程中使用GOPATH

8.2 創建包(package)——編寫自己的代碼擴展

8.3 包在程式啟動前的初始化入口:init

8.4 導出標示符——讓外部訪問包的類型和值

8.4.1 導出包內標示符

8.4.2 導出結構體及接口成員

8.5 導入包(import)——在代碼中使用其他的代碼

8.5.1 默認導入的寫法

8.5.2 導入包後自定義引用的包名

8.5.2 匿名導入包——只導入包但不使用包內類型和數值

8.5.3 理解包導入初始化順序

8.6 示例:工廠模式自動註冊 ——管理多個包的結構體

第9章 並發

9.1 輕量級執行緒(goroutine)——根據需要隨時創建的“執行緒”

9.1.1 使用普通函式創建goroutine

9.1.2 使用匿名函式創建goroutine

9.1.3 調整並發的運行性能(GOMAXPROCS)

9.1.4 理解並發和並行

9.1.5 理解Go的協作程式(goroutine)和普通的協作程式(coroutine)

9.2 通道(channel) ——在多個goroutine間通信的管道

9.2.1 通道的特性

9.2.2 聲明通道類型

9.2.3 創建通道

9.2.4 使用通道傳送數據

9.2.5 使用通道接收數據

9.2.6 關閉通道後繼續使用通道

9.2.7 示例:並發列印

9.2.8 單向通道——通道中的單行道

9.2.9 帶緩衝的通道——允許在通道中保存一定數量的數據

9.2.10 通道的多路復用——同時處理接收和傳送多個通道的數據

9.2.11 示例:模擬遠程過程調用(RPC)

9.2.12 示例:使用通道回響計時器的事件

9.3 示例:Telnet回音伺服器——TCP伺服器的基本結構

9.4 同步——保證並發環境下數據訪問的正確性

9.4.1 競態檢測——檢測代碼在並發環境下可能出現的問題

9.4.2 互斥鎖(sync.Mutex)——保證同時只有一個goroutine可以訪問共享資源

9.4.3 讀寫互斥鎖(sync.RWMutex)——在讀比寫多的環境下比互斥鎖更高效

9.4.4 等待組(sync.WaitGroup)——保證在並發環境中完成指定數量的任務

第10章 反射

10.1 反射的類型對象(reflect.Type)

10.1.1 理解反射的類型(Type)與種類(Kind)

10.1.2 指針與指針指向的元素

10.1.3 使用反射獲取結構體的成員類型

10.1.4 結構體標記(Struct Tag)——對結構體欄位的額外信息標記

10.2 反射的值對象(reflect.Value)

10.2.1 使用反射值對象包裝任意值

10.2.2 從反射值對象獲取被包裝的值

10.2.3 使用反射訪問結構體的成員欄位的值

10.2.4 判定反射的零值和空

10.2.5 使用反射值對象修改變數的值

10.2.6 通過類型創建類型的實例

10.2.7 使用反射調用函式

10.3 示例:將結構體的數據保存為JSON格式的文本數據

第11章 編譯與工具

11.1 編譯(go build)

11.1.1 go build無參數編譯

11.1.2 go build + 檔案列表

11.1.3 go build + 包

11.1.4 go build編譯時的附加參數

11.2 編譯後運行(go run)

11.3 編譯並安裝(go install)

11.2 一鍵獲取代碼、編譯並安裝(go get)

11.2.1 遠程包的路徑格式

11.2.2 go get + 遠程包

11.2.3 go get使用時的附加參數

11.3 測試(go test)

11.3.1 單元測試——測試和驗證代碼的框架

11.3.2 基準測試——獲得代碼記憶體占用和運行效率的性能數據

11.4 性能分析(go pprof)——發現代碼性能問題的調用位置

11.4.1 安裝第三方圖形化顯式分析數據工具(Graphviz)

11.4.2 安裝第三方性能分析分析代碼包

11.4.3 性能分析代碼

第12章 避坑與技巧

12.1 合理的使用並發特性

12.1.1 了解goroutine的生命期時再創建goroutine

12.1.2 避免在不必要的地方使用通道

12.2 反射:性能和靈活性的雙刃劍

12.3 接口的nil判斷

12.4 map的多鍵索引——多個數值條件可以同時查詢

12.4.1 基於哈希值的多鍵索引及查詢

12.4.2 利用map特性的多鍵索引及查詢

12.4.3 總結

12.5 優雅的處理TCP粘包——一套完備的TCP協定的客戶端和伺服器框架

作者介紹

作者簡介

徐波 遊戲行業從業十餘年,多年的全棧遊戲開發者,慕課網講師,開源愛好者,眾多Gopher之一。2009年創立“戰魂小築部落格”,自2012年開始接觸Go語言,開源項目cellnet以及tabtoy導表工具,被業內大為認同。

相關詞條

熱門詞條

聯絡我們