1.Go語言環境搭建及基礎知識linux
Go語言官方網站(http://golang.org)
代碼包文檔網站(http://godoc.org)
Go語言中文網(http://studygolang.com)git
Go語言開發包下載路徑:
https://golang.google.cn/dl/github
《Go併發編程實戰》所用到的源碼實例下載路徑:
https://github.com/hyper-carrot/goc2pgolang
《Go併發編程實戰》完整PDF下載路徑,我放到網盤了: 編程
連接:http://pan.baidu.com/s/1pLSJ2Tt 密碼:k8gjwindows
1.1 go語言配置環境變量架構
windows下:
: GOROOT={你的Go語言的根目錄}
在環境變量PATH後追加;%GOROOT%\bin併發
linux下:
: Go語言官方建議把go文件夾複製到/usr/local目錄中,但也能夠複製到其餘目錄;編輯/etc/profile文件,以下:
export GOROOT=/usr/local/go
export PATH=\$PATH:\$GOROOT/bin
保存/etc/profile文件,使用source /etc/profile使配置生效。
(具體linux配置環境變量能夠Google,Baidu,這裏不贅述了)ide
注意: 路徑鏈接符windows下是"\",linux下是 "/"函數
Go語言還有兩個隱含的環境變量----GOOS和GORACH
: GOOS表明程序構建環境的目標操做系統,其值能夠是liunx,windows,freebsd,darwin;
GORACH表明程序構建環境的目標計算架構,其值能夠是386,amd64或arm;
以後提到的平臺相關目錄是經過\${GOOS}_\${GORACH}的方式來命名的。
(如Go歸檔文件的存放路徑就是根據「平臺相關目錄」來指定的)
設置好環境變量後,在命令行中輸入go出現以下信息,表示成功。
Go is a tool for managing Go source code. Usage: go command [arguments] The commands are: build compile packages and dependencies clean remove object files doc show documentation for package or symbol env print Go environment information fix run go tool fix on packages fmt run gofmt on package sources generate generate Go files by processing source get download and install packages and dependencies install compile and install packages and dependencies list list packages run compile and run Go program test test packages tool run specified go tool version print Go version vet run go tool vet on packages Use "go help [command]" for more information about a command. Additional help topics: c calling between Go and C buildmode description of build modes filetype file types gopath GOPATH environment variable environment environment variables importpath import path syntax packages description of package lists testflag description of testing flags testfunc description of testing functions Use "go help [topic]" for more information about that topic.
1.2 工做區
Go代碼必須放在工做區中,工做區其實就是一個對應於特定工程的目錄,它包含3個子目錄src目錄,pkg目錄和bin目錄。
src目錄
: 用於以代碼包的形式組織並保存Go源碼文件。這裏的代碼包,與src下的子目錄一一對應。例如,若一個源碼文件被聲明爲屬於代碼包logging,那麼它就應當被保存在src目錄下名爲logging的子目錄中。固然,咱們也能夠把Go源碼文件直接放於src目錄下,但這樣的Go源碼文件就只能被聲明爲屬於main代碼包了。除非用於臨時測試或演示,通常仍是建議把Go源碼文件放入特定的代碼包中。
pkg目錄
: 用於存放經由go install命令構建安裝後的代碼包(包含Go庫源碼文件)的"*.a"歸檔文件。該目錄與GOROOT目錄下的pkg功能相似,區別在於,工做區中的pkg目錄專門用來存放用戶代碼的歸檔文件。構建和安裝用戶源碼的過程通常會以代碼包爲單位進行,好比logging包被編譯安裝後,將生成一個名爲logging.a的歸檔文件,並存放在當前工做區的pkg目錄下的平臺相關目錄中。
bin目錄
: 與pkg目錄相似,在經過go install命令完成安裝後,保存由Go命令源碼文件生成的可執行文件。在Linux操做系統下,這個可執行文件通常是一個與源碼文件同名的文件。在Windows操做系統下,這個可執行文件的名稱是源碼文件名稱加.exe後綴。
1.3 GOPATH
工做區的目錄路徑須要添加到環境變量GOPATH中。不然,即便處於同一個工做區(事實上,未被加入到環境變量GOPATH中的目錄不該該稱做工做區),代碼之間也沒法經過絕對代碼包路徑完成調用。在實際開發中,工做區每每有多個,這些工做區的目錄路徑都須要添加至GOPATH中。
如Linux下有兩個工做區:
~/Go/lib
~/Go/goc2p
修改/etc/profile文件,添加環境變量GOPATH的內容:
export GOPATH=\$HOME/Go/lib:\$HOME/Go/goc2p
保存/etc/profile文件,並用source命令使配置生效。
注意:
- GOPATH中不要包含環境變量GOROOT的值(即Go的安裝目錄路徑),將Go語言自己的工做區和用戶的工做區嚴格地分開;
- 經過Go工具中的代碼獲取命令go get,能夠將指定項目的源碼下載到咱們在環境變量GOPATH中設定的第一個工做區中,並在其中完成構建和安裝的過程。
Windows下直接在系統變量中添加GOPATH環境變量便可,其中值爲你的工做區的根目錄。
1.4 源碼文件
Go語言的源碼文件分爲3類:Go庫源碼文件,Go命令源碼文件和Go測試源碼文件。
命令源碼文件
聲明爲屬於main代碼包,而且包含無參數聲明和結果聲明的main函數的源碼文件。這類文件能夠獨立運行(使用go run命令),也能夠被go build或go install命令轉換爲可執行文件。
同一個代碼包中的全部源碼文件,其所屬代碼包的名稱必須一致。若是命令源碼文件和庫源碼文件處於同一代碼包中,該包就沒法正確執行go build和go install命令。換句話說,這些源碼文件也就沒法被編譯和安裝。所以,命令源碼文件一般會單獨放在一個代碼包中。通常狀況下,一個程序模塊或軟件的啓動入口只有一個。
同一個代碼包中能夠有多個命令源碼文件,可經過go run命令分別運行它們。但經過go build和go install命令沒法編譯和安裝該代碼包。因此通常狀況下,不建議把多個命令源碼文件放在同一個代碼包中。
當代碼包中有且僅有一個命令源碼文件時,在文件所在目錄中執行go build命令,便可在該目錄下生成一個與目錄同名的可執行文件;若使用go install命令,則可在當前工做區的bin目錄下生成相應的可執行文件。
庫源碼文件
存在於某個代碼包中的普通源碼文件。一般,庫源碼文件聲明的包名會與它實際所屬的代碼包(目錄)名一致,且庫源碼文件中不包含無參數聲明和無結果聲明的main函數。如在basic/set目錄下執行go install命令,成功地安裝了basic/set包,並生成一個名爲set.a的歸檔文件。歸檔文件的存放目錄由如下規則產生:
- 安裝庫源碼文件時所生成的歸檔文件會被存放到當前工做區的pkg目錄中。
- 根據被編譯的目標計算機架構,歸檔文件會被放置在pkg目錄下的平臺相關目錄中。如上的set.a在個人64位window系統上就是pkg\windows_amd64目錄中。
- 存放歸檔文件的目錄的相對路徑與被安裝的代碼包的上一級代碼包的相對路徑是一致的。第一個相對路徑就是相對於工做區的pkg目錄下的平臺相關目錄而言的,而第二個相對路徑是相對於工做區的src目錄而言的。若是被安裝的代碼包沒有上一級代碼包(也就是說它的父目錄就是工做的src目錄),那麼它的歸檔文件就會被直接存放到當前工做區的pkg目錄的平臺相關目錄下。如basic包的歸檔文件basic.a總會被直接存放到pkg\windows_amd64目錄下,而basic/set包的歸檔文件set.a則會被存放到pkg\ windows_amd64\basic目錄下。
測試源碼文件
這是一種特殊的庫文件,能夠經過執行go test命令運行當前代碼包下的全部測試源碼文件。成爲測試源碼文件的充分條件有兩個:
- 文件名須要以」_test.go」結尾
- 文件中須要至少包含該一個名稱爲」Test」開頭或」Benchmark」開頭,擁有一個類型爲」testing.T」或」testing.B」的參數的函數。類型」testing.T」或」testing.B」分別對應功能測試和基礎測試所需的結構體。
當在某個代碼包中執行go test命令,該代碼包中的全部測試源碼文件就會被找到並運行。
注意:存儲Go代碼的文本文件須要以UTF-8編碼存儲。若是源碼文件中出現了非UTF-8編碼的字符,則在運行、編譯或安裝時,Go會拋出「illegal UTF-8 sequence」的錯誤。
1.5 代碼包
Go語言中的代碼包是對代碼進行構建和打包的基本單元。
包聲明
在Go語言中,代碼包中的源碼文件名能夠是任意的;這些任意名稱的源碼文件都必須以包聲明語句做爲文件中代碼的第一行。好比src目錄下的代碼包basic/set包中的全部源碼文件都要先聲明本身屬於basic/set包:
package set
package是Go語言中用於包聲明語句的關鍵字。Go語言規定包聲明中的包名爲代碼包路徑的最後一個元素。如上,basic/set包的包路徑爲basic/set,而包聲明中的包名則爲set。除了命令源碼文件不論存放在哪一個包中,都必須聲明爲屬於main包。
包導入
代碼包的導入使用代碼包導入路徑。代碼包導入路徑就是代碼包在工做區的src目錄下的相對路徑,好比basic的絕對路徑爲E:\Go\goc2p\src\basic\set,而E:\Go\goc2p是被包含在環境變量GOPATH中的工做區目錄路徑,則其代碼包導入路徑就是basic/set。
import basic/set
當導入多個代碼包時,須要用圓括號括起它們,且每一個代碼包名獨佔一行。在調用被導入代碼包中的函數或使用其中的結構體、變量或常量時,須要使用包路徑的最後一個元素加」.」的方式指定代碼所在的包。
若是咱們有兩個包logging和go_lib/logging,而且有相同的方法NewSimpleLogger(),且有一個源碼文件須要導入這兩個包:
import ( "logging" "go_lib/logging" )
則這句代碼logging.NewSimpleLogger()就會引發衝突,Go語言沒法知道logging. 表明的是哪個包。因此,在Go語言中,若是在同一個源碼文件中導入多個代碼包,那麼代碼包路徑的最後一個元素不能夠重複。
若是用這段代碼包導入代碼,在編譯代碼時,Go語言會拋出」logging redeclared as imported package name」的錯誤。若是確實須要導入,當有這類重複時,咱們能夠給它們起個別名來區別:
import ( la "logging" lb "go_lib/logging" )
調用包中的代碼:
var logger la.Logger = la.NewSimpleLogger()
這裏沒必要給每一個引發衝突的代碼包都起一個別名,只要可以區分它們就能夠了。
若是咱們想直接調用某個依賴包的程序,就能夠用」.」來代替別名。
import ( . "logging" lb "go_lib/logging" )
在當前源碼文件中,能夠直接進行代碼調用了:
var logger Logger = NewSimpleLogger()
Go語言把變量、常量、函數、結構體和接口統稱爲程序實體,而把它們的名字統稱爲標識符。標識符能夠是任何Unicode編碼能夠表示的字母字符、數字以及下劃線」_」,而且,首字母不能是數字或下劃線。
標識符的首字母的大小寫控制着對應程序實體的訪問權限。若是標識符的首字母是大寫的,那麼它對應的程序實體就能夠被本代碼包以外的代碼訪問到,也能夠稱其爲可導出的。不然對應的程序實體就只能被本包內的代碼訪問。固然,還須要有如下兩個額外條件:
- 程序實體必須是非局部的。局部程序實體是被定義在函數或結構體的內部。
- 代碼包所在的目錄必須被包含在環境變量GOPATH中的工做區目錄中。
若是代碼包logging中有一個叫作getSimpleLogger的函數,那麼光從這個函數的名字上咱們就能夠看出,這個函數是不能被包外代碼調用的。
若是咱們只想初始化某個代碼包而不須要再當前源碼文件中使用那個代碼包中的任何代碼,既能夠用」_」來代替別名
import ( _ 「logging」 )
包初始化
在Go語言中,能夠有專門的函數負責代碼包初始化。這個函數須要無參數聲明和結果聲明,且名稱必須爲init,以下:
func init() { println("Initialize") }
Go語言會在程序真正執行前對整個程序的依賴進行分析,並初始化相關的代碼包。也就是說,全部的代碼包初始化函數都會在main函數(命令源碼文件中的入口函數)以前執行完成,並且只會執行一次。而且,當前代碼包中的全部全局變量的初始化都會在代碼包初始化函數執行前完成。這就避免了在代碼包初始化函數對某個變量進行賦值以後又被該變量聲明中賦予的值覆蓋掉的問題。
這裏舉出《Go併發編程實戰》中的例子,幫助理解上面的包初始化,以下:
package main // 命令源碼文件必須在這裏聲明本身屬於main包 import ( // 引入了代碼包fmt和runtime "fmt" "runtime" ) func init() { // 包初始化函數 fmt.Printf("Map: %v\n", m) // 先格式化再打印 // 經過調用runtime包的代碼獲取當前機器所運行的操做系統以及計算架構 // 然後經過fmt包的Sprintf方法進行字符串格式化並賦值給變量info info = fmt.Sprintf("OS: %s, Arch: %s", runtime.GOOS, runtime.GOARCH) } // 非局部變量,map類型,且已初始化 var m map[int]string = map[int]string{1: "A", 2: "B", 3: "C"} var info string // 非局部變量,string類型,未被初始化 func main() { // 命令源碼文件必須有的入口函數 fmt.Println(info) // 打印變量info }
命名源碼文件名爲initpkg_demo.go,並保存到工做區的basic/pkginit包中。以下圖爲我本機運行的結果:
在同一個代碼包中,能夠存在多個代碼包初始化函數,甚至代碼包內的每個源碼文件均可以定義多個代碼包初始化函數。Go語言編譯器不能保證同一個代碼包中的多個代碼包初始化函數的執行順序。若是要求按特定順序執行的話,能夠考慮使用Channel(Go語言併發編程模型的一員)進行控制。
Go語言承認兩個特殊的代碼包名稱----all 和 std. all表明了環境變量GOPATH中包含的全部工做區中的全部代碼包,而std則表明了Go語言標準庫中的全部代碼包。
標準命令概述
- build 編譯給定的代碼包或Go語言源碼文件及其依賴包
- clean 清除執行其餘go命令後遺留的目錄和文件
- doc 執行godoc命令以打印指定代碼包。
- env 打印Go語言環境信息
- fix 執行go tool fix命令以修正給定代碼包的源碼文件中包含的過期語法和代碼調用
- fmt 執行gofmt命令以格式化戈丁代碼包中的源碼文件。
- generate generate Go files by processing source
- get 下載和安裝給定的代碼包及其依賴包
- install 編譯和安裝給定的代碼包及其依賴包
- list 顯示給定代碼包的信息
- run 編譯並運行給定的命令源碼文件
- test 測試給定的代碼包
- tool 運行Go語言的特殊工具
- version 顯示當前安裝的Go語言的版本信息
- vet run go tool vet on packages
在執行上述命令的時候能夠經過附加一些額外的標記來定製命令的執行過程,這些標記能夠看作是命令的特殊參數,這些特殊參數能夠添加到命令名稱和命令的真正參數中間,以下:
- -a 強行從新構建全部涉及的Go語言代碼包(包括Go語言標準庫中的代碼包),即便它們已是最新的了。
- -n 使命令僅打印在執行期間使用到的全部命令,而不真正執行它們。
- -v 打印出命令執行過程當中涉及的Go語言代碼包的名字。這些代碼包通常包括咱們本身給定的目標代碼包,有時候還會包括該代碼包直接或間接依賴的代碼包。
- -work 打印出命令執行時生成和使用的臨時工做目錄的名字,且命令執行完成後不對它進行刪除。
- -x 打印出命令執行期間使用到的全部命令。
經常使用的Go語言的特殊工具,以下:
- fix 能夠把給定代碼包的全部Go語言源碼文件中的舊版本代碼修改成新版本。它是咱們升級Go語言版本後會使用到的工具。
- vet 用於檢查Go語言源碼中靜態錯誤的簡單工具。可使用它檢測一些常見的Go語言代碼編寫錯誤。
- pprof 用於以交互的方式訪問一些性能概要文件。命令將會分析給定的概要文件,並根據要求提供高可讀性的輸出信息。這個工具能夠分析的概要文件包括CPU概要文件、內存概要文件和程序阻塞概要文件。這些內含Go語言運行時信息的概要文件能夠經過標準庫代碼包runtime和runtime/pprof中的程序來生成。
- cgo 用於幫助Go語言代碼使用C語言代碼庫,以及使用Go語言代碼能夠被C語言代碼引用。
最後附上《Go併發編程實戰》做者郝林託管到GitHub的Go命令教程,裏面涉及了Go命令和工具的詳細用法:
https://github.com/hyper-carrot/go_command_tutorialGo語言學習的第一天,之後持續更新。。。