原文:How to Write Go Codehtml
go tool
:安裝好 Go 以後自帶的 cmd 工具,用於 fetch, build and install Go packages.go tool 對代碼的組織結構有特定的要求 git
Def: 一個 workspace 是一個有特定文件結構 hierarchy 的文件夾,其中根目錄下有兩個文件夾:github
src
:包含 Go 源代碼bin
:包含可執行命令go tool 會構建(build)和安裝(install)可執行代碼(binaries)到 bin
文件夾中。src
文件夾下的子文件夾即會包含多個 repo。golang
For Example:bash
bin/
hello # command executable
outyet # command executable
src/
github.com/golang/example/
.git/ # Git repository metadata
hello/
hello.go # command source
outyet/
main.go # command source
main_test.go # test source
stringutil/
reverse.go # package source
reverse_test.go # test source
golang.org/x/image/
.git/ # Git repository metadata
bmp/
reader.go # package source
writer.go # package source
... (many more repositories and packages omitted) ...
複製代碼
GOPATH
環境變量Def:GOPATH
環境變量指向了你的 workspace 的位置。它在 Unix 的默認值是在你 Home 文件夾下的 $HOME/go
或是 Windows 裏的 %USERPROFILE%\go
(一般是 C:\Users\YourName\go
)。工具
若是你但願設置多個不一樣的位置,能夠經過設置 GOPATH
來解決。學習
GOPATH 不能與安裝 Go 的位置同樣 fetch
能夠經過 go env GOPATH
看到目前的 GOPATH
。ui
開放 workspace's 裏的 bin 子目錄到 PATH(就是在 $GOPATH/bin/
下的 cmd 能夠直接調用了):spa
$ export PATH=$PATH:$(go env GOPATH)/bin
複製代碼
設置 $GOPATH
到環境變量:
$ export GOPATH = $(go env GOPATH)
複製代碼
Def: 一個 import path 是表明一個 package 的惟一指代字段(String)。一個 package 的 import path 表明了其在一個 workspace 中的具體位置(也多是一個遠程 repo)。
"fmt"
和 "net/http"
。github.com/user
做爲 base path在咱們本身的電腦上,咱們能夠先設置一個 base path(注意,這裏 user 你能夠本身隨便寫):
$ mkdir -p $GOPATH/src/github.com/user
複製代碼
咱們來開發第一個項目,咱們假設這個 package path 是 github.com/user/hello 並創建一個子文件夾做爲 package 的文件夾:
$ mkdir $GOPATH/src/github.com/user/hello
複製代碼
下一步則是創建一個文件 hello.go
做爲源代碼:
package main
import "fmt"
func main() {
fmt.Println("Hello, world.")
}
複製代碼
下一步就是用 go tool 來 build 和 install 這段代碼:
$ go install github.com/user/hello
複製代碼
這個命令會觸發:
GOPATH
環境變量已經設置了 workspace 的位置)相應的 package path github.com/user/hello
$ cd $GOPATH/src/github.com/user/hello
,那麼就能夠直接輸入 $ go install
便可bin
文件夾下並命名爲 hello,即 $GOPATH/bin/hello
$GOPATH/bin
加入到 $PATH
環境變量裏,那麼 hello
已經能夠做爲命令使用。也就是以下效果:
$ $GOPATH/bin/hello
Hello, world.
複製代碼
或
$ hello
Hello, world.
複製代碼
一樣,像是創建一個 Program 同樣,咱們創建一個 Library 文件夾 stringutil
:
$ mkdir $GOPATH/src/github.com/user/stringutil
複製代碼
而後在 stringutil
文件夾裏創建一個文件 reverse.go
:
// Package stringutil contains utility functions for working with strings.
package stringutil
// Reverse returns its argument string reversed rune-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)
}
複製代碼
也如同上面所說,咱們來構建(build)它,逐一這裏咱們只 build 不 install 由於這是一個 Library:
$ go build github.com/user/stringutil
複製代碼
構建好後,若是咱們想在咱們的 Program 中引用這個 stringutil
Library 則經過更新 GOPATH/src/github.com/user/hello
中的 hello.go
文件:
package main
import (
"fmt"
"github.com/user/stringutil"
)
func main() {
fmt.Println(stringutil.Reverse("!oG ,olleH"))
}
複製代碼
下一步,咱們從新 install hello
:
$ go install github.com/user/hello
複製代碼
那麼相應的 cmd hello
經過引用 stringutil
Library 也有了新的輸出:
$ hello
Hello, Go!
複製代碼
這時,若是咱們看 workspace 中的變化和文件結構就是:
bin/
hello # command executable
src/
github.com/user/
hello/
hello.go # command source
stringutil/
reverse.go # package source
複製代碼
其中:
bin/hello
是 install 以後的可執行 binary 程序github.com/user/hello
是 hello
Programgithub.com/user/stringutil
是 stringutil
Library每個 Go 源代碼文件的第一行必須是:
package name
複製代碼
而這裏 name 是 package 被引用時的默認名。在 Go 語言的常規使用中,import path 的最後一個元素即爲 package name,例如:package 經過 "crypto/rot13"
引用,那麼這個 package 的名字應該是 rot13
。
可運行的 cmd(也就是要被 install)的 binary 名必須是 main
。而 package name 並不必定要不重複,只要 import paths 惟一便可。也就是 "util1/util"
和 "util2/util"
是不一樣的。
此處內容精煉,這裏不作闡述了。
一個 import path 能夠用來獲取一個遠程的 package(如 Git 或 Mercurial),go tool 會自動下載遠程的 repo。例如,Go 官方的示例代碼被存儲在 GitHub 上,地址爲 github.com/golang/example
,使用 go get
命令便可自動 fetch, build and install,go get
會將 package 自動下載到 $GOPATH
中的第一個 workspace 中:
$ go get github.com/golang/example/hello
$ $GOPATH/bin/hello
Hello, Go examples!
複製代碼
這個時候的 workspace 文件夾結構變成了:
bin/
hello # command executable
src/
github.com/golang/example/
.git/ # Git repository metadata
hello/
hello.go # command source
stringutil/
reverse.go # package source
reverse_test.go # test source
github.com/user/
hello/
hello.go # command source
stringutil/
reverse.go # package source
reverse_test.go # test source
複製代碼
這個時候,你可能會疑慮,就是 hello
以前是由 github.com/user/hello
來定義的,而如今被 github.com/golang/example/hello
覆蓋。
GOPATH
: golang.org/wiki/Settin…