標籤:golang
本文章來自於 Google官方的翻譯: How to Write Go Code?
http://godoc.golangtc.com/doc/code.html
介紹
這篇文檔舉例證明了一個簡單地 Go package 並且介紹了 go tool,標準的方法來 fetch, build,and install Go package and commands.
如果要使用 go tool,那麼就必須將程式碼群組織成一種特殊的形式。 請仔細的閱讀這篇文檔,它會教你採用最簡單的方法來安裝運行你的Go程式。
程式碼群組織Workspace 工作空間
Go tool 被設計成用來開源公用倉庫中的代碼,儘管或許你不需要發布你的代碼, 但是環境的設定還是一樣的。
Go的原始碼必須存放在 workspace中。 workspace 是一個目錄(directory hierachy),在這個目錄下有三個子目錄
src 包含 Go 原始碼檔案, 原始碼檔案組織成 packages (one package per directory)
pkg 包含 package objects (二進位的包)
bin 包含 可執行檔命令 command(可執行檔二進位檔案)
go tool 編譯(build) 原始碼檔案(source packages),並且將 resulting binaries 安裝在 pkg 和 bin 目錄下面。
src 目錄下麵包含多個 版本控制的倉庫, (比如 Git 或者 Mercurial) 用來 跟蹤一個或者多個 source package的開發進度。
下面給你一個真實環境中的 workspace 是什麼樣子的:
bin/ hello # 可執行檔命令 outyet # 可執行檔命令pkg/ linux_amd64/ github/golang/example/ stringutil.a # pakcage objectssrc/ github.com/golang/example/ .git/ # git repository metadata hello/ hello.go # command source outyet/ main.go # command source main_test.go # test source stringuitl/ reverse.go # package source reverse_test.go # test source
這個工作空間 包含一個 代碼倉庫repository( example倉庫),example 倉庫由兩個命令 command (hello, outyet)和一個庫library組成(stringutil)
一個典型的 workspace 會包含多個 source repositories,包含很多 pakcages 和 commands。
大部分的 Go programmers 會 keep all their Go source code and dependencies in a single workspace. (將所有的Go原始碼和依賴儲存在一個工作空間中)。
另外 從上述例子中也可以看到, bin/ 中命令的名字,pkg/中庫的名字 都是檔案夾的文字。 src/中包的名字和你 import 時候的名字不一定一樣,這一點要區別。
GOPATH 環境變數
GOPATH 環境變數 指明了 你的工作空間的位置。 它很可能是你在編寫Go代碼的時候需要唯一設定的環境變數。
開始編程:
1. 建立一個工作空間目錄。
2. 設定 GOPATH 環境變數。
GOPATH目錄可以是任意的,唯一的要求是不能是你安裝Go時的目錄(/usr/local/go)。
$ mkdir $HOME/go$ export GOPATH=$HOME/go
為了方便,將工作空間的 bin 子目錄 加入到 你的 PATH 環境變數中。
$ export PATH=$PATH:$GOPATH/bin
Package pathes 包路徑
packages path 不是 library path,雖然二者有聯絡。
標準庫中的包,是由短路徑(short path)決定的,比如 “fmt”和”net/http”。對於你自己的包,你必須選擇一個 base path,這個base path不能和別的包路徑衝突。
如果你將你的代碼儲存在一個 源倉庫中(source repository),那麼你應該使用 the root of that source repository as your base path.
比如你有一個 GitHub帳號: github.com/usr,這 應該是你的 base path.
注意: 你或許不需要發布你的代碼 to remote repository before you can build it. 但是將程式碼群組成成 code repository是一個好的習慣。
舉例:我們使用 github.com/usr作為你的base path. 在你的workspace中建立一個目錄來儲存你的代碼。
$ mkdir -p $GOPATH/src/github.com/usr
第一個 program
為了編譯和運行一個簡單地程式,首先選擇一個 package path(這裡使用 github.com/usr),建立一個 package directory (包目錄)
$ mkdir $GOPATH/src/github.com/usr/hello
第二:在包目錄下建立一個檔案 名為 hello.go,包含如下的代碼
package mainimport "fmt"func main() { fmt.Println("Hello, World.\n")}
第三: 使用 go tool 來 build and install 這個程式
$ go install github.com/user/hello
注意: 你可以你的電腦的任何檔案夾下面運行這個命令。 go tool 會在 $GOPATH 指定工作空間下面搜尋 github.com/usr/hello 這個包,並且編譯安裝這個包。
當然, 如果你在 package directory 下面運行 go install 你就可以忽略 package path。
$ cd $GOPATH/github.com/usr/hello$ go install
這個命令會 build the hello command, 產生一個可執行檔二進位檔案。然後將這個可執行檔二進位檔案安裝到工作目錄的 bin目錄下面,檔案名稱為 hello (在Windows下面為 hello.ext,可以看到可執行二進位檔案名稱和目錄的名稱保持一致)。 在我們的例子中是: $GOPATH/bin/hello,也就是 $HOME/go/bin/hello
當有錯誤發生的時候,go tool只會 print output,而不會產生二進位檔案。 如果這些命令沒有產生 output(輸出),就表示他們運行成功了。
現在你可以 通過輸入 hello命令的全名 來運行這個命令了
$ $GOPATH/bin/hellohello, world
或者如果你已經將 $GOPATH/bin 加入到 PATH中:
$ hellohello, world
如果你使用原始碼版本控制系統,現在這是一個好的時機來 initialize a repository, add the files,and commit you first chagne. Again, this step is optional: you do not need to use source control to write Go code.
$ cd $GOPATH/src/github.com/usr/hello$ git initInitialized empty Git repository in /home/user/go/src/github.com/user/hello/.git/$ git add hello.go$ git commit -m "initial commit"[master (root-commit) 0b4507d] initial commit 1 file chagned, 1 insertion(+) create mode 100644 hello.go
將代碼 Push 到遠端倉庫留作讀者作為一個聯絡吧。
第一個 Library
現在我們寫一個 Library,並且在 hello 程式中使用這個庫。
- 首先, 選擇一個 package path (我們使用
github.com/user/stringutil),建立這個 package directory
$ mkdir $GOPATH/src/github.com/usr/stringutil
- 在這個目錄中建立一個檔案
reverse.go
// Package stringutil contains utility functions for working with strings.//Reverse returns its argument string reversed run-wise left to right.func Reverse(s string) string { r := []rune(s) for i , j := 0, len(r)-1; i < len(r)/2; i,j = i+1, j-1 { r[i], r[j] = r[j], r[i] } return string(r)}
- 測試 這個 pckage compiles with 命令
go build:
$ go build github.com/user/stringutil
或者你在 這個目錄下面,只需要
$ go build
即可。
go build 不會產生任何的檔案。 我們需要使用 go install 可以 將 package object 放置在 workspace下的 pkg目錄下。
$ go install
- 為了確認
stringutil 已經建立(build),我們需要修改 hello.go 檔案。
package mainimport ( "fmt" "github.com/usr/stringutil")func main() { fmt.Printf(stirngutil.Reverse("!oG, olleH"))}
- 當 go tool 安裝一個 package 或者 一個 binary(可執行二進位),它也會 installs whatever dependencies it has (安裝它所依賴的檔案). 所以當你 intall
hello 程式的時候
$ go install github.com/user/hell
stringutil 也會自動安裝。
運行新版本的程式,你會看見如下結果:
$ helloHello, Go!
經過了上述的步驟,你的工作空間現在應該是下面的情況:
bin/ hello # command executalbe 可執行命令pkg/ linux_amd64/ # this will reflect you OS and architecture github.com/usre/ stringutil.a # package objectsrc/ github.com/user/ hello/ hello.go # command source stringutil/ reverse.go # package source
可以看到, go install 將 stringutil.a放置在 pkg/linux_amd64的目錄下, 這個目錄 mirrors its source directory. 這是因為 以後 go tool 會找到 package object,並且會避免重新編譯。 linux_amd64是為了平台交叉編譯,將會反映你的作業系統和電腦的體繫結構。
Go command exectualbes are statically linked。(go command 執行是靜態連結的) The package objects need not be present to run Go program.(pakcage object 在Go程式執行的時候是不需要的)。
Go 工作空間 深度解析