從一個簡單的程序開始解釋,將下面的內容放進test.go文件中,路徑隨意:linux
package main import ( "fmt" ) func main() { fmt.Println("Hello World") }
Go經過包的方式管理程序,每一個Go源代碼文件都必須聲明本身所在的包,正如上面的package main
聲明本身所在的包是main包。git
每一個程序都必須有一個main包,main包做爲整個程序的編譯入口包,main包中的main()函數做爲程序的執行入口。編程
import關鍵字用來導入其它包,導入某個包以後就能在當前文件中使用這個包中的函數,例如上面的main包導入fmt包後,可使用fmt包中的函數Println()。windows
而後可使用go的build工具編譯這個test.go文件:bash
$ go build test.go
編譯後,將在當前路徑下生成一個可執行二進制文件:Windows下生成的是test.exe文件,Unix下生成的是test文件。既然是可執行文件,固然能夠直接執行:編程語言
$ ./test
將輸出"Hello World"。函數
也能夠直接經過go的run工具將編譯和運行兩個步驟合二爲一:工具
$ go run test.go Hello World
go run
不會生成可執行的二進制文件,它其實是將編譯獲得的文件放進一個臨時目錄,而後執行,執行完後自動清理臨時目錄。ui
每一個go代碼文件只能且必須使用package語句聲明一個包,也就是說一個文件中不能包含多個包。spa
Go中有兩種類型的包,或者說有兩種類型的文件:
注意:
在go的官方文檔中將go的二進制可執行程序稱爲命令,有時候還會將go的源代碼文件稱爲命令的源文件。可執行程序和包相反,包通常是做爲"庫"文件存在,用於導入而非用於執行
共享庫中包含一些函數,這些函數比較通用,因此放進共享庫方便函數複用。例如fmt包中的Println函數,處處都在使用這個函數,且由於fmt包是標準庫(Standary library),不管是誰均可以去使用這個包。
有兩種類型的庫文件:標準庫和第三方的庫。標準庫是隨Go安裝的時候放在go安裝目錄下的($GOROOT/src/
),第三方庫是放在workspace下的。關於workspace後文再說。
共享庫能夠被import導入(例如fmt包)。因爲導入操做是在編譯期間實現的,共享庫中不該該包含任何輸出型語句。
Go中對庫文件要求比較嚴格,或者說強制性的規範。它要求庫文件中package聲明的包名必須和目錄名稱相同,且同一個目錄下只容許有一個包,但同一個目錄下能夠有多個庫文件片斷,只不過這些庫文件中必須都使用package聲明它的包名爲目錄名。例如:
src/mycode |- first.go |- second.go |- third.go
若是這三個文件都是庫文件,則它們都必須且只能使用package mycode
聲明本身的包爲mycode。go build
的時候,會將它們合併起來。若是聲明的包名不是mycode,go build會直接忽略它。
固然,對main包就無所謂了,它不是庫文件,能夠放在任何地方,對目錄名沒有要求。但若是使用go install
,則有額外的要求,見後文。
Go經過名稱首字母的大小寫決定屬性是否容許導出:
因此當庫文件被導入時,只有這個庫文件中以大寫字母開頭的常量、變量、函數等纔會被導出,才能夠在其餘文件中使用。
例如,庫文件abc.go中:
func first() {} func Second() {}
當導入這個包的時候,因爲first()函數首字母小寫,外界沒法使用它,它只能在本身的包abc.go中使用,對外界不可見。大寫字母開頭的Second()函數會被導入,因此可用。
GOPATH
設置workspace的路徑workspace
下,固然,這不是必須的Go和其它編程語言在組織項目的時候有所不一樣,其它語言通常每一個項目都有一個單獨的workspace,且workspace通常和版本控制倉庫進行綁定。
如今設置GOPATH環境變量,假設設置爲/gocode
echo 'export GOPATH=/gocode' >>/etc/profile.d/gopath.sh chmod +x /etc/profile.d/gopath.sh source /etc/profile.d/gopath.sh
go env GOPATH
肯定是否正確:
$ go env GOPATH /gocode
每一個workspace都是一個目錄,這個目錄下至少包含三個目錄:
括號中給的名稱是go官方文檔中常見的別名稱呼。
因此,先建立這3個目錄
mkdir -p /gocode/{src,pkg,bin}
GOPATH環境變量指定workspace的位置,用來指示go從哪裏搜索go源文件/包,例如import時從哪一個路徑搜索包並導入。GOROOT環境變量用於指定go的安裝位置。go須要導入包時,會從GOPATH和GOROOT所設置的位置處搜索包。
默認位置爲$HOME/go
(Unix)或%USERPROFILE\go%
(Windows)。能夠手動設置GOPATH環境變量的路徑從而指定workspace的位置,能夠指定爲多個目錄,多個目錄時使用冒號分隔目錄(Unix系統)或使用分號分隔目錄(Windows系統)。注意,絕對不能將其設置爲go的安裝目錄,即不能和GOROOT環境變量重複。
例如,windows下設置d:\gocode
目錄爲GOPATH的路徑:
setx GOPATH d:\gocode
Unix下設置$HOME/gocode
目錄爲GOPATH的路徑:
mkdir ~/gocode export GOPATH=~/gocode echo 'GOPATH=~/gocode' >>~/.bashrc
go env
或go env GOPATH
命令能夠輸出當前有效的GOPATH路徑。
$ go env | grep GOPATH GOPATH="/root/gocode" $ go env GOPATH /root/gocode
先寫兩個go文件,一個是可執行go文件test.go,一個是共享庫strutils.go,將它們放在workspace的src下。
$ mkdir -p $GOPATH/src/{hello,strutils} $ tree -C . ├── bin ├── pkg ├── src │ ├── hello │ │ └── test.go │ └── strutils │ └── strutils.go
注意,上面故意將test.go放在名爲hello的目錄下,能夠將其放在src下的任何非庫文件目錄下(例如不能放進strutils目錄下),名稱不要求。
hello/test.go的內容以下:
package main import ( "fmt" "strutils" ) func main() { fmt.Println("Hello World") fmt.Println(strutils.ToUpperCase("hello world")) }
strutils/strutils.go的內容以下:
package strutils import ( "strings" ) func ToUpperCase(s string) string{ return strings.ToUpper(s) } func ToLowerCase(s string) string{ return strings.ToLower(s) }
go build
能夠用於編譯,編譯時會對import導入的包進行搜索,搜索的路徑爲標準庫所在路徑$GOROOT/src
、workspace下的src目錄。它只會生成額外的可執行文件放在當前目錄下,不會生成額外的庫文件。但須要注意,生成的可執行文件名稱可能會出乎意料:
例如進入到目錄src/hello
下,對test.go的文件進行編譯,如下三種build路徑均可用成功編譯:
cd src/hello go build # 生成的可執行文件名爲hello go build . # 生成的可執行文件名爲hello go build test.go # 生成的可執行文件名爲test
前二者是等價的,當go build
以目錄的形式進行編譯,則生成的可執行文件名爲目錄名。當go build
以go代碼文件名的方式進行編譯,則生成的可執行程序名爲go源碼文件名(去掉後綴.go或增長後綴.exe)。
go還有一個工具install,go install
的操做稱爲安裝,將文件安裝到合適的位置。go install
時會先進行編譯,而後將編譯後的二進制文件保存到workspace的bin目錄下,將編譯後的庫文件(稱爲包對象文件,以".a"爲後綴)放在pkg目錄下。
注意,go install
時必須先進入到$GOPATH/src
下,且只能對目錄進行操做,不能對具體的go文件操做,由於go認爲包和目錄名相同。給go install
指定一個目錄名,就表示編譯這個包名。
例如,對src/hello下的test.go進行安裝,因爲它導入了strutils包,因此會自動將strutils也安裝好:
$ cd $GOPATH/src $ go install hello $ tree $GOPATH /gocode ├── bin │ └── hello # 二進制程序文件名爲hello,而非test ├── pkg │ └── linux_amd64 │ └── strutils.a # 庫文件 └── src ├── hello │ └── test.go └── strutils └── strutils.go
還能夠單獨對庫文件進行安裝:
$ rm -rf $GOPATH/bin/* $GOPATH/pkg/* $ cd $GOPATH/src $ go install strutils /gocode ├── bin ├── pkg │ └── linux_amd64 │ └── strutils.a └── src ├── hello │ └── test.go └── strutils └── strutils.go
若是省略目錄名,則表示對當前目錄下的包進行安裝:
$ cd $GOPATH/src/hello $ go install
再次提醒,go install
前先進入到$GOPATH/src
目錄下。
因爲go install能夠直接安裝二進制文件到$GOPATH/bin
,因此出於方便執行這些二進制程序,能夠將這個目錄放進PATH環境變量。
$ export PATH=$PATH:`go env GOPATH`/bin
1.因爲能夠將全部go項目放在同一個$GOPATH
目錄下,爲了區分src下的項目目錄和庫文件目錄,建議將每一個項目目錄設置深一點。
例如:
bin pkg src |- /first/project |- main.go |- myliba |- a.go |- b.go |- mylibb |- c.go |- d.go |- /second/project |- main.go |- lib |- a.go |- b.go
2.go install時,先進入到項目目錄下。
3.庫文件的名稱(也是目錄名)要選取合理,儘可能短,但卻儘可能見名知意,也儘可能減小名稱重複的概率。
例如util這種名稱處處都是,能夠修改成numutil、nameutil等。