# 1.2 GOPATH與工作空間 前面我們在安裝Go的時候看到需要設定GOPATH變數,Go從1.1版本到1.7必須設定這個變數,而且不能和Go的安裝目錄一樣,這個目錄用來存放Go原始碼,Go的可執行檔案,以及相應的編譯之後的套件檔案。所以這個目錄下面有三個子目錄:src、bin、pkg 從go 1.8開始,GOPATH環境變數現在有一個預設值,如果它沒有被設定。 它在Unix上預設為$HOME/go,在Windows上預設為%USERPROFILE%/go。 ## GOPATH設定 go 命令依賴一個重要的環境變數:$GOPATH Windows系統中環境變數的形式為`%GOPATH%`,本書主要使用Unix形式,Windows使用者請自行替換。 *(注:這個不是Go安裝目錄。下面以筆者的工作目錄為示例,如果你想不一樣請把GOPATH替換成你的工作目錄。)* 在類別 Unix 環境下大概這樣設定: ```sh export GOPATH=/home/apple/mygo ``` 為了方便,應該新建以上資料夾,並且上一行加入到 `.bashrc` 或者 `.zshrc` 或者自己的 `sh` 的配置檔案中。 Windows 設定如下,新建一個環境變數名稱叫做GOPATH: ```sh GOPATH=c:\mygo ``` GOPATH允許多個目錄,當有多個目錄時,請注意分隔符,多個目錄的時候Windows是分號,Linux系統是冒號,當有多個GOPATH時,預設會將go get的內容放在第一個目錄下。 以上 $GOPATH 目錄約定有三個子目錄: - src 存放原始碼(比如:.go .c .h .s等) - pkg 編譯後生成的檔案(比如:.a) - bin 編譯後生成的可執行檔案(為了方便,可以把此目錄加入到 $PATH 變數中,如果有多個gopath,那麼使用`${GOPATH//://bin:}/bin`新增所有的bin目錄) 以後我所有的例子都是以mygo作為我的gopath目錄 ## 程式碼目錄結構規劃 GOPATH下的src目錄就是接下來開發程式的主要目錄,所有的原始碼都是放在這個目錄下面,那麼一般我們的做法就是一個目錄一個專案,例如: $GOPATH/src/mymath 表示mymath這個套件或者可執行應用,這個根據package是main還是其他來決定,main的話就是可執行應用,其他的話就是套件,這個會在後續詳細介紹package。 所以當新建應用或者一個程式碼套件時都是在src目錄下新建一個資料夾,資料夾名稱一般是程式碼套件名稱,當然也允許多級目錄,例如在src下面新建了目錄$GOPATH/src/github.com/astaxie/beedb 那麼這個套件路徑就是"github.com/astaxie/beedb",套件名稱是最後一個目錄beedb 下面我就以mymath為例來講述如何編寫套件,執行如下程式碼 ```sh cd $GOPATH/src mkdir mymath ``` 新建檔案sqrt.go,內容如下 ```go // $GOPATH/src/mymath/sqrt.go原始碼如下: package mymath func Sqrt(x float64) float64 { z := 0.0 for i := 0; i < 1000; i++ { z -= (z*z - x) / (2 * x) } return z } ``` 這樣我的套件目錄和程式碼已經新建完畢,注意:一般建議package的名稱和目錄名保持一致 ## 編譯應用 上面我們已經建立了自己的套件,如何進行編譯安裝呢?有兩種方式可以進行安裝 1、只要進入對應的套件目錄,然後執行`go install`,就可以安裝了 2、在任意的目錄執行如下程式碼`go install mymath` 安裝完之後,我們可以進入如下目錄 ```sh cd $GOPATH/pkg/${GOOS}_${GOARCH} //可以看到如下檔案 mymath.a ``` 這個.a檔案是套件,那麼我們如何進行呼叫呢? 接下來我們新建一個應用程式來呼叫這個套件 新建套件mathapp ```sh cd $GOPATH/src mkdir mathapp cd mathapp vim main.go ``` `$GOPATH/src/mathapp/main.go`原始碼: ```go package main import ( "mymath" "fmt" ) func main() { fmt.Printf("Hello, world. Sqrt(2) = %v\n", mymath.Sqrt(2)) } ``` 可以看到這個的package是`main`,import裡面呼叫的套件是`mymath`,這個就是相對於`$GOPATH/src`的路徑,如果是多級目錄,就在import裡面引入多級目錄,如果你有多個GOPATH,也是一樣,Go會自動在多個`$GOPATH/src`中尋找。 如何編譯程式呢?進入該應用目錄,然後執行`go build`,那麼在該目錄下面會產生一個mathapp的可執行檔案 ```sh ./mathapp ``` 輸出如下內容 ```sh Hello, world. Sqrt(2) = 1.414213562373095 ``` 如何安裝該應用,進入該目錄執行`go install`,那麼在$GOPATH/bin/下增加了一個可執行檔案mathapp, 還記得前面我們把`$GOPATH/bin`加到我們的PATH裡面了,這樣可以在命令列輸入如下命令就可以執行 ```sh mathapp ``` 也是輸出如下內容 Hello, world. Sqrt(2) = 1.414213562373095 這裡我們展示如何編譯和安裝一個可執行的應用,以及如何設計我們的目錄結構。 ## 取得遠端套件 go語言有一個取得遠端套件的工具就是`go get`,目前go get支援多數開源社群(例如:github、googlecode、bitbucket、Launchpad) go get github.com/astaxie/beedb >go get -u 引數可以自動更新套件,而且當go get的時候會自動取得該套件依賴的其他第三方套件 透過這個命令可以取得相應的原始碼,對應的開源平臺採用不同的原始碼控制工具,例如github採用git、googlecode採用hg,所以要想取得這些原始碼,必須先安裝相應的原始碼控制工具 透過上面取得的程式碼在我們本地的原始碼相應的程式碼結構如下 $GOPATH src |--github.com |-astaxie |-beedb pkg |--相應平臺 |-github.com |--astaxie |beedb.a go get本質上可以理解為首先第一步是透過原始碼工具clone程式碼到src下面,然後執行`go install` 在程式碼中如何使用遠端套件,很簡單的就是和使用本地套件一樣,只要在開頭import相應的路徑就可以 import "github.com/astaxie/beedb" ## 程式的整體結構 透過上面建立的我本地的mygo的目錄結構如下所示 bin/ mathapp pkg/ 平臺名/ 如:darwin_amd64、linux_amd64 mymath.a github.com/ astaxie/ beedb.a src/ mathapp main.go mymath/ sqrt.go github.com/ astaxie/ beedb/ beedb.go util.go 從上面的結構我們可以很清晰的看到,bin目錄下面存的是編譯之後可執行的檔案,pkg下面存放的是套件,src下面儲存的是應用原始碼 ## links * [目錄]() * 上一節: [安裝Go](<01.1.md>) * 下一節: [GO 命令](<01.3.md>)