## 包
每個包都對應一個獨立的名字空間。
每個源文件都是以包的聲明語句開始,用來指明包的名字。當包被導入的時候,包內的成員將通過類似tempconv.CToF的形式訪問。而包級別的名字,例如在一個文件聲明的類型和常量,在同一個包的其他源文件也是可以直接訪問的,就好像所有代碼都在一個文件一樣。
## 導入包
在Go語言程序中,每個包都有一個全局唯一的導入路徑。
除了包的導入路徑,每個包還有一個包名,包名一般是短小的名字(并不要求包名是唯一的),包名在包的聲明處指定。按照慣例,**一個包的名字和包的導入路徑的最后一個字段相同**,例如gopl.io/ch2/tempconv包的名字一般是tempconv。
導入語句將導入的包綁定到一個短小的名字,然后通過該短小的名字就可以引用包中導出的全部內容。
但是我們也可以綁定到另一個名稱,以避免名字沖突。
如果導入了一個包,但是又沒有使用該包將被當作一個編譯錯誤處理。這種強制規則可以有效減少不必要的依賴。
## 包的初始化
包的初始化首先是解決包級變量的依賴順序,然后按照包級變量聲明出現的順序依次初始化:
~~~
var a = b + c // a 第三個初始化, 為 3
var b = f() // b 第二個初始化, 為 2, 通過調用 f (依賴c)
var c = 1 // c 第一個初始化, 為 1
func f() int { return c + 1 }
~~~
如果包中含有多個.go源文件,它們將按照發給編譯器的順序進行初始化,Go語言的構建工具首先會將.go文件根據文件名排序,然后依次調用編譯器編譯。
對于在包級別聲明的變量,如果有初始化表達式則用表達式初始化,還有一些沒有初始化表達式的,例如某些表格數據初始化并不是一個簡單的賦值過程。在這種情況下,我們可以用一個特殊的init初始化函數來簡化初始化工作。每個文件都可以包含多個init初始化函數
~~~
func init() { /* ... */ }
~~~
這樣的init初始化函數除了不能被調用或引用外,其他行為和普通函數類似。在每個文件中的init初始化函數,在程序開始執行時按照它們聲明的順序被自動調用。
每個包在解決依賴的前提下,以導入聲明的順序初始化,每個包只會被初始化一次。因此,如果一個p包導入了q包,那么在p包初始化的時候可以認為q包必然已經初始化過了。初始化工作是自下而上進行的,main包最后被初始化。以這種方式,**可以確保在main函數執行之前,所有依賴的包都已經完成初始化工作了**。
- 基本語法
- 申明變量
- 常量
- 數據類型
- 強制類型轉換
- 獲取命令行參數
- 指針
- 概述
- new函數
- 函數
- 概述
- 不定參數類型
- 有返回值
- 函數類型
- 回調函數
- 匿名函數和閉包
- 延遲調用defer
- 工程管理
- 工作區
- src,pkg和bin目錄
- 復合類型
- 概述
- 數組
- 概述
- 聲明并初始化
- 拷貝傳值
- slice
- 概述
- 創建切片
- 切片截取
- 切片和底層數組的關系
- slice常用方法
- 切片做函數參數
- map
- 概述
- map操作
- 結構體
- 概述
- 結構體初始化
- 結構體比較
- 結構體作為函數參數
- 結構體前加&
- 面向對象
- 概述
- 匿名組合
- 方法
- 值語義和引用語義
- 方法集
- 方法的繼承
- 方法重寫
- 方法值
- 接口
- 接口定義和實現
- 多態的表現
- 接口繼承
- 接口轉換
- 空接口
- 類型斷言
- 異常處理
- error接口
- panic
- recover
- 文本文件處理
- 字符串操作
- 正則表達式
- json處理
- 文件操作
- 標準設備文件操作
- 并發編程
- 概述
- 并發和并行
- go語言并發優勢
- goroutine
- goroutine概述
- 創建goroutine
- 主協程先退出
- runtime包
- Gosched
- Goexit
- GOMAXPROCE
- channel
- 多資源競爭
- channel類型
- 無緩沖channel
- 有緩沖channel
- 關閉channel
- 單向channel
- 單向channel特性
- 定時器
- Timer
- Ticker
- select
- select作用
- 超時
- sync
- 競爭狀態
- 網絡編程
- 網絡概述
- 網絡協議
- 分層模型
- 網絡分層架構
- 層與協議
- 每層協議的功能
- 鏈路層
- 網絡層
- 傳輸層
- 應用層
- socket編程
- 組合和繼承
- 注意事項
- 細節
- go語言實現隊列
- google工程師golang
- 基礎語法
- 內建容器
- 面向"對象"
- 依賴管理
- 面向接口
- 函數式編程
- 錯誤處理和資源管理
- 測試與性能調優
- goroutine
- channel
- golang問題集
- 斷言和類型轉換
- Go語言圣經
- 入門
- 程序結構
- 命名
- 聲明
- 變量
- 賦值
- 類型
- 包和文件
- 作用域
- 基礎數據類型
- 整數
- 浮點數
- 復數
- 布爾型
- 字符串
- 常量
- 復合數據類型
- 數組
- slice
- map
- 結構體
- json
- 文本和HTML模板
- 函數
- 函數聲明
- 錯誤
- 函數值
- 匿名函數
- defer
- panic
- recover
- 方法
- 方法聲明
- 指針對象的方法
- 封裝
- 接口
- 說明
- 接口是合約
- 實現接口的條件
- 接口值
- 類型斷言
- 通過類型斷言詢問行為
- 類型開關
- Goroutines和Channels
- 協程
- channels
- 無緩沖channel
- 串聯的channel
- 有緩沖channel
- 并發的循環
- select多路復用
- 并發的退出
- 并發問題的自我思考
- 基于共享變量的并發
- 競爭條件
- 互斥鎖
- 讀寫鎖
- 內存同步
- sync.Once
- 協程和線程
- 包和工具
- 測試
- 反射
- 什么是反射
- 為什么需要反射
- reflect.Type和reflect.Value
- 通過reflect.Value修改值
- 底層編程