您可以在这里读到这篇文章最新状态:
http://www.lijiaocn.com/blog/2014/07/23/Go的工程管理.html
Go的工程管理
创建时间: 2014/07/23 10:16:39 修改时间: 2014/07/23 14:09:57 作者:lijiao
摘要
Go自身提供了很好的工程化管理, 几乎不依赖IDE, 大赞。
下面涉及Go的环境搭建(linux)、代码编辑器(vim)、源码管理、单元测试框架、单元性能测试(benchmark)。
环境搭建
安装go开发套件
下载安装文件go1.3.linux-amd64.tar.gz, 解压到/opt
在.bashrc中添加:
export GOROOT=/opt/go #go install dir
export PATH=$PATH:$GOROOT/bin:$GOPATH/bin
(可选)配置VIM
将/opt/go/misc/vim中内容复制到.vim/bundle/go中(vim插件安装), 包含以下功能:
:Godoc //显示光标所在位置的内容的godoc
创建go模板文件, ~/.vim/template/template.go (需要安装有vim template插件):
:% s/ctime/=strftime("%Y/%m/%d %H:%M:%S")/ge
:% s/ltime/=strftime("%Y/%m/%d %H:%M:%S")/ge
:% s/year/=strftime("%Y")/ge
//Copyright year. All rights reserved.
//Author: lja
//Createtime: ctime Lastchange:ltime
//changlog: 1. create by lja
package
workspace
设置workspace:
export GOPATH=/opt/example
export PATH=$PATH:$GOPATH/bin
mkdir -p $GOPATH/src
mkdir -p $GOPATH/bin
mkdir -p $GOPATH/pkg
第一个执行程序
$GOPATH/src/hello/hello.go
//Copyright 2014. All rights reserved.
//Author: lja
//Createtime: 2014/07/23 06:28:50 Lastchange:2014/07/23 06:28:50
//changlog: 1. create by lja
package main
import (
| "fmt"
)
func main() {
| fmt.Printf("Hello world!
")
}
编译、安装:
go install hello //注意目标目录的表示方法: 从src/hello/hello.go中去掉了src和hello.go
在$GOPATH/bin目录下生成程序hello:
[lja@localhost bin]$ pwd
/opt/example/bin
[lja@localhost bin]$ ls
hello
注意如果设置了环境变量GOBIN, hello程序将被安装到GOBIN所指的目录
第一个程序库(library)
创建目录:
mkdir $GOPATH/src/hellopkg
创建文件, $GOPATH/src/hellopkg/hellopkg.go
//Copyright 2014. All rights reserved.
//Author: lja
//Createtime: 2014/07/23 07:10:53 Lastchange:2014/07/23 07:10:53
//changlog: 1. create by lja
package hellopkg
import (
| "fmt"
)
func Helloworld(){ //注意首字母是大写,表示可以被外部调用
| fmt.Printf("Hello world from hellopkg!
")
}
编译安装:
go install hellopkg
在$GOPATH/pkt目录生成hellopkg.a
[lja@localhost linux_amd64]$ pwd
/opt/example/pkg/linux_amd64
[lja@localhost linux_amd64]$ ls
hellopkg.a
注意: hellopkg.go中隶属的package最好与所在的目录名一致。如果不一致, 在import的时候需要包含目录名, 使用的时候需要使用package名
第一次使用pkg
创建目录:
mkdir $GOPATH/src/hellopkg_use
创建文件, $GOPATH/src/hellopkg/hello_pkg.go
//Copyright 2014. All rights reserved.
//Author: lja
//Createtime: 2014/07/23 07:15:07 Lastchange:2014/07/23 07:15:07
//changlog: 1. create by lja
package main
import (
| "hellopkg"
)
func main() {
| hellopkg.Helloworld()
}
编译安装:
go install hellopkg_use
在$GOPATH/bin目录下生成程序hellopkg_use:
[lja@localhost bin]$ pwd
/opt/example/bin
[lja@localhost bin]$ ls
hello hellopkg_use
注意编译后的可执行程序的名称是目录名hellppkt_use, 不是文件名hello_pkg.go中的hello_pkg
通过上面过程可以发现, 如果src的子目录中包含package main, 这个子目录被编译成可执行程序, 否则编译成pkg
第一个远程代码
安装gocode, 远程地址: https://github.com/nsf/gocode
go get -u github.com/nsf/gocode
gocode源码被下载到src
[lja@localhost gocode]$ pwd
/opt/example/src/github.com/nsf/gocode
[lja@localhost gocode]$ ls
autocompletecontext.go client.go cursorcontext.go declcache.go docs emacs-company _gccgo _goremote os_posix.go package.go ripper.go scope.go _testing vim
autocompletefile.go config.go debian decl.go emacs formatters.go gocode.go LICENSE os_windows.go README.md rpc.go server.go utils.go
gocode程序被编译生成到bin:
[lja@localhost bin]$ ls
gocode hello hellopkg_use
[lja@localhost bin]$ pwd
/opt/example/bin
[lja@localhost bin]$ ls
gocode hello hellopkg_use
gocode可以使在用vim编辑go程序时给出代码提示, 用法如下:
安装vim插件:
cd $GOPATH/src/github.com/nsf/gocode/vim
./pathogen_update.sh //里面有三个安装脚本, 根据vim的情况做选择
配置gocode:
gocode set propose-builtins true //提示go自带的内容
gocode set autobuild true //自动编译pkg
用vim打开.go文件, 补全时键入Ctrl+x,Ctrl+o, 需要注意只会提示已经被import的pkg中成员。
自动化文档
go的注释可以自动转换成文档。只需将注释写在package、func之前, 中间不能有空行
例如:
//这时一个hellopkt
//你可以用它来输出一行Hello world
package hellopkt
//这是一个helloword函数
func Helloworld(){
fmt.Printf("Hello world from hellopkg!
")
}
在代码中这样写入注释后,就可以直接使用godoc查看文档,例如:
[lja@localhost hellopkg]$ godoc hellopkg
PACKAGE DOCUMENTATION
package hellopkg
import "hellopkg"
这是一个hellopkt 你可以用它来输出一行Hello world
FUNCTIONS
func Helloworld()
这时一个Helloworld函数
[lja@localhost hellopkg]$ godoc hellopkg Helloworld
func Helloworld()
这时一个Helloworld函数
另外,go自身的源码中专门用了一个doc.go文件作为pkg的说明文件,可以借鉴这种方式. 例如/opt/go/src/pkg/fmt/doc.go
/*
Package fmt implements formatted I/O with functions analogous
to C's printf and scanf. The format 'verbs' are derived from C's but
are simpler.
Printing
The verbs:
General:
%v the value in a default format.
when printing structs, the plus flag (%+v) adds field names
%#v a Go-syntax representation of the value
%T a Go-syntax representation of the type of the value
%% a literal percent
....
....
*/
package fmt
测试框架
测试源码的命名必须采用如下格式:
Target_test.go //Target没有要求,建议以文件为单位,每个目标文件file.go对应一个测试文件file_test.go
测试源码必须包含testing, 测试函数必须按照如下格式定义:
func Test函数名(t *testing.T){
}
例如 $GOPATH/src/hellopkg/hellopkg_test.go
//Copyright 2014. All rights reserved.
//Author: lja
//Createtime: 2014/07/23 09:06:19 Lastchange:2014/07/23 09:06:19
//changlog: 1. create by lja
package hellopkg
import (
| "testing"
)
func TestHelloworld(t *testing.T) {
| //t.Errorf("没有什么好测的, 给出个测试不通过的例子")
}
测试过程:
go test hellopkg //执行hellopkg包的测试程序
go test //执行所有测试程序
测试结果如下:
[lja@localhost hellopkg]$ go test hellopkg
--- FAIL: TestHelloworld (0.00 seconds)
hellopkg_test.go:13: 没有什么好测的, 给出个测试不通过的例子
FAIL
FAIL hellopkg 0.004s
Benchmark
Benchmark是测试框架的一部分, 用来获得函数的运行效率信息。参考下面的文章:
在$GOPATH/src/hellopkg/hellopkg.go中添加函数Multi:
func Multi(n int, m int)int{
return n*m
}
在$GOPATH/src/hellopkg/hellopkg_test.go中添加Benchmark测试代码:
func BenchmarkMulti(b *testing.B) {
for i := 0; i < b.N; i++ {
Multi(88,99)
}
执行test,并执行Benchmark
//-bench参数正则匹配要执行的benchmark函数
[lja@localhost hellopkg]$ go test hellopkg -bench=BenchmarkMulti
PASS
BenchmarkMulti 2000000000 1.04 ns/op
ok hellopkg 2.211s
如果test没有通过, 后续的benchmark测试也不会执行
不执行test, 只执行Benchmark
//-run参数正则匹配要执行的test函数, 这里随便写一个XXX, 使正则匹配结果为空
[lja@localhost hellopkg]$ go test hellopkg -run=XXX -bench=BenchmarkMulti
PASS
BenchmarkMulti 2000000000 1.09 ns/op
ok hellopkg 2.311s
文献
- http://xxx "Name"