### 概述
go代碼必須放在工作區中.工作區其實就是一個對應于特定工程的目錄,它應包含3個子目錄 : src目錄,pkg
目錄,和bin目錄 .
* src : 用于以代碼包的形式組織并保存go源碼文件.(比如 : go.c .h .s等)
* pkg : 用于存放經由go install命令構建安裝后的代碼包(包含go庫源碼文件)的 ".a"歸檔文件
* bin : 與pkg目錄類似,在通過go install命令完成安裝后,保存由go命令源碼文件生成的可執行文件 .
目錄src用于包含所有的源代碼,是go命令行工具一個強制的規則,而pkg和bin則無需手動創建,如果必要go
命令行工具在構建過程中會自動創建這些目錄.
特別需要注意的是,只有當環境變量GOPATH中只包含一個工作區的目錄路徑時,go install命令才會把命令
源碼安裝到當前工作區的bin目錄下.若環境變量GOPATH中包含多個工作區的目錄路徑,像這樣執行go install
命令就會失效,此時必須設置環境變量GOBIN.
### GOPATH設置
為了能夠構建這個工程,需要先把所需工程的根目錄加入到環境變量GOPATH中.否則,即使處于同一工作目
錄(工作區) ,代碼之間也無法通過絕對代碼包路徑完成調用 .在實際開發環境中,工作目錄往往有多個.這些
工作目錄的目錄路徑都需要添加至GOPATH . 當有多個目錄時,請注意分隔符,多個目錄的時候Windows是
分好,linux是冒號,當有多個GOPATH時,默認會將go get的內容放在第一個目錄下 .
~~~
go env //查看go的環境變量
~~~
### 包
所有go語言的程序都會組織成若干組文件,每組文件被稱為一個包,這樣每個包的代碼都可以作為很小的服
用單元,被其他項目引用 . 一個包的源代碼保存在一個或多個以.go為文件后綴名的源文件中, 通常一個包
所在目錄路徑的后綴是包的導入路徑 .
#### 自定義包
對于一個較大的應用程序,我們應該將他們的功能分隔成邏輯單元,分別在不同的包里實現.我們創建的自定
義包最好放在GPPATH的src目錄下(或者GOPATH src的某個子目錄) . 在go語言中,代碼包中的源碼文件名
可以是任意的.但是,這些任意名稱的源碼文件都必須以包聲明語句作為文件的第一行,每個包都對應一個
獨立的名字空間 .
~~~
package packageName
~~~
**包中成員以名稱首字母大小寫決定訪問權限 :**
* public : 首字母大寫,可被包外訪問
* private : 首字母小寫,僅包內成員可以訪問
**注意 : 同一個目錄下不能定義不同的package**
### main包
在go語言中,命名為main的包具有特殊的含義 . go語言的編譯程序會試圖把這種名字的包編譯為二進制可
執行文件.所以用go語言編譯的可執行程序都必須有一個名叫main的包.一個可執行程序有切只有一個
main包 . 當編譯器發現某個包的名字為main時,它一定也會發現名為main()的函數,否則不會創建可執行文
件. main()函數是程序的入口,所以,如果沒有這個函數,程序就沒有辦法開始執行.程序編譯時,會使用聲明
main包的代碼所在的目錄的目錄名作為而進行可執行文件的文件名 .
### main包和init函數
go里面有兩個保留的函數:init函數(能夠應用于所有的package)和main函數(只能應用于package main).這
兩個函數在定義時不能有任何的參數和返回值.雖然一個package里面可以寫任意多個init函數 ,但這無論
是對于可讀性還是以后的可維護性來說,我們都強烈建議用戶在一個熬成卡個中每個文件只寫一個init函數
.go程序會自動調用init()和main(),所以你不需要在任何地方調用者兩個函數,每個package中的init函數都是
可選的,但package main就必須包含一個main函數 . 每個包可以包含任意多個init函數,這些函數都會在程
序執行開始的時候被調用,所有被編譯器發現的init函數都會安排在main函數之前執行 .init函數用在設置
包,初始化變量或者其他要在程序運行前優先完成的引導工作 .程序的初始化和執行都起始于main包.如果
main包還導入了其他的包,那么久會在編譯時將它們依次導入.有時一個包會被多個包同時導入,那么它指
揮被導入一次(例如很多包可能都會用到fmt包,但它只會被導入一次,因為沒有必要導入多次) .當一個包被
導入時,如果該包還導入了其他的包,那么會將其他包導入進來,然后在對這些包中的包級常量和變量進行
初始化,接著執行init函數(如果有的話) ,一次類推.等所有被導入的包都加載完畢了,就會開始對main包中的
包級常量和變量進行初始化,然后執行main包中的init函數(如果存在的話),最后執行main函數.下圖詳細的
解釋了整個執行過程 .

### _ 操作
~~~
import _ "fmt" //忽略此包
~~~
### 總結
聲明語句最先執行, 然后是init()函數,再然后是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修改值
- 底層編程