原文: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…