192 lines
6.5 KiB
Markdown
192 lines
6.5 KiB
Markdown
# 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
|
||
* [目錄](<preface.md>)
|
||
* 上一節:[安裝 Go](<01.1.md>)
|
||
* 下一節:[GO 命令](<01.3.md>)
|