> For the complete documentation index, see [llms.txt](https://willh.gitbook.io/build-web-application-with-golang-zhtw/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://willh.gitbook.io/build-web-application-with-golang-zhtw/01.0/01.2.md).

# 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 環境下大概這樣設定：

```bash
export GOPATH=/home/apple/mygo
```

為了方便，應該建立以上資料夾，並且上一行加入到 `.bashrc` 或者 `.zshrc` 或者自己的 `sh` 的配置檔案中。

Windows 設定如下，建立一個環境變數名稱叫做 GOPATH：

```bash
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 為例來講述如何編寫套件，執行如下程式碼

```bash
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`

安裝完之後，我們可以進入如下目錄

```bash
cd $GOPATH/pkg/${GOOS}_${GOARCH}
//可以看到如下檔案
mymath.a
```

這個.a 檔案是套件，那麼我們如何進行呼叫呢？

接下來我們建立一個應用程式來呼叫這個套件

建立套件 mathapp

```bash
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 的可執行檔案

```bash
./mathapp
```

輸出如下內容

```bash
Hello, world.  Sqrt(2) = 1.414213562373095
```

如何安裝該應用，進入該目錄執行`go install`，那麼在$GOPATH/bin/下增加了一個可執行檔案 mathapp, 還記得前面我們把`$GOPATH/bin`加到我們的 PATH 裡面了，這樣可以在命令列輸入如下命令就可以執行

```bash
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

* [目錄](https://github.com/doggy8088/build-web-application-with-golang-zhtw/tree/4cbbaa31bdfc3678915eb91f23db2f1bad554a20/preface.md)
* 上一節: [安裝 Go](/build-web-application-with-golang-zhtw/01.0/01.1.md)
* 下一節: [GO 命令](/build-web-application-with-golang-zhtw/01.0/01.3.md)
