本文参考于: How to Write Go Code
代码组织
工作空间
Go tool先天就是设计来与开源仓库协作的,不管你愿不愿意发布你的代码,构建开发环境的方式是一样的。
Go代码必须保存在一个工作空间里, 一个工作空间要有三个根目录
-
src Go源代码
-
pkg Go库文件
-
bin 包含可执行命令
一个工作空间的示例:
bin/ hello # command executable outyet # command executable pkg/ linux_amd64/ github.com/golang/example/ stringutil.a # package object 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 github.com/golang/project1/ ...... github.com/golang/project2/ ......
设置GOPATH环境变量
GOPATH是Go中唯一必须需要设置的环境变量, GOPATH就是工作空间的路径, 并且GOPATH可
以设置多个值,区别是使用go get
命令的时候默认将下载的包安装在GOPATH第一个路径
下面,我自己一般设置两个路径作为GOPATH的值,一个用于专门下载第三方包,一个作为
自己的工作环境, 这有的好处是可以在代码版本控制时, 不受第三方库的影响
如:
# $HOME/golang作为第三方包的下载目录
# $HOME/github/golang作为自己的开发目录
$ export GOPATH="$HOME/golang:$HOME/github/golang"
# 将每个GOPATH下面的bin目录添加到PATH变量
$ export PATH=$PATH:$GOROOT/bin:${GOPATH//://bin:}/bin
包路径
无论你是否要发布你的程序, 你都应该以要发布的方式来构建你的程序,最好的包名是 github.com/user
$ mkdir -p $GOPATH/src/github.com/user
第一个Go程序
下面,我将介绍如何将从头构建一个简单的go程序.
首先, 我们以/data/github/golang
为工作空间
$ mkdir -p /data/github/golang
$ cd /data/github/golang
$ export GOPATH=$(pwd)
为了创建一个简单的程序. 首先要选择包路径, 如github.com/crazygit/hello
, 并创建对于的目录结构
$ mkdir -p $GOPATH/src/github.com/crazygit/hello
在目录$GOPATH/src/github.com/crazygit/hello
里创建hello.go
package main
import "fmt"
func main() {
fmt.Println("Hello world")
}
使用go工具编译并安装程序
$ cd $GOPATH
$ go install github.com/crazygit/hello
或者
$ cd $GOPATH/github.com/crazygit/hello
$ go install
执行了之后,可以看到$GOPATH
中多了一个bin
目录,里面有一个名为hello
的可执行文件
$ $GOPATH/bin/hello
Hello, world.
第一个Go库
让我们再创建一个库,同样,先创建包路径github.com/crazygit/stringutil
$ mkdir $GOPATH/src/github.com/crazygit/stringutil
在里面再创建一个名为reverse.go
package stringutil
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)
}
编译
$ cd $GOPATH
$ go build github.com/crazygit/stringutil
编译过程不会有什么文件产生, 可以使用go install
, 它会创建pkg目录
并生成pkg/linux_amd64/github.com/crazygit/stringutil.a
文件.
修改hello.go
,让它使用我们刚刚创建的库
import (
"fmt"
"github.com/crazygit/stringutil"
)
func main() {
fmt.Println("Hello world")
fmt.Printf(stringutil.Reverse("!oG ,olleH"))
}
安装,当安装的的时候,它会自动根据安装依赖,所以安装hello
时, 它会自动安装stringutil
$ go install github.com/crazygit/hello
运行
$ $GOPATH/bin/hello
Hello, Go!
包名
Go代码文件的第一句话必须是
package name
name就是要引起的包名,所有在同一个包下的包名也一样
go里面为了方便,会使用引入包路径的最后一段作为包名,如 crazygit/rot14
的包名就是rot14
可执行的命令必须引入包package main
测试
Go自带了一个使用go test
的测试框架,为了写一个测试文件。
应该创建一个文件名_test.go
结尾的文件,函数名为如TestXXX
的, 并且有参数t *testing.T
让我们为stringutil包创建测试$GOPATH/src/github.com/crazygit/stringutil/reverse_test.go
package stringutil
import "testing"
func TestReverse(t *testing.T) {
cases := []struct {
in, want string
}{
{"Hello, world", "dlrow ,olleH"},
{"Hello, 世界", "界世 ,olleH"},
{"", ""},
}
for _, c := range cases {
got := Reverse(c.in)
if got != c.want {
t.Errorf("Reverse(%q) == %q, want %q", c.in, got, c.want)
}
}
}
执行测试
$ go test github.com/crazygit/stringutil
ok github.com/crazygit/stringutil 0.002s
第三方包
$ go get github.com/golang/example/hello
$ $GOPATH/bin/hello
Hello, Go examples!
如果当前包已经存在,go get
会跳过下载
到此,我们对go有了个大致的印象,虽然有些地方看不懂,不过没有关系,我们后面会继续学习。