内容简介:注意这是和其他编程环境不同的地方:每个项目都有单独的工作空间,并且工作空间与版本控制仓库紧密绑定工作根目录有两个目录:
预览
- Go程序员通常让所有的 Go 代码在一个单独的工作空间(workspace).
- 一个工作空间包含很多版本控制仓库(比如,通过git管理)
- 每个仓库包含一个或者多个包(packages).
- 每个包由单独的目录下的Go源文件组成.
- 包的目录路径决定他的 导入路径
注意这是和其他编程环境不同的地方:每个项目都有单独的工作空间,并且工作空间与版本控制仓库紧密绑定
工作空间
工作根目录有两个目录:
- src 包含够源文件
- bin 包含可执行命令
go tool
构建并安装binaries到 bin
目录
src
子目录一般包含多个版本控制仓库(比如Git或者Mercurial)追踪一个或多个源包的开发。
下面展示工作空间的结构:
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) ...</pre>
上面的树显示工作空间包含两个仓库( example
和 image
)。 example
仓库包含两个命令( hello
和 outyet
)和一把库( stringutil
). image
仓库包含 bmp
包和其他的一些内容
经典的工作空间包含多个源仓库,源仓库包含多个包和命令。大多数的Go程序员将所有的Go源代码和依赖放在一个单独的工作空间。
注意,不应该使用 symbolic links 关联文件或者目录到工作空间。
GOPATH环境变量
GOPATH环境变量指定工作空间的位置。默认是在home目录里的go目录,比如Unix的 $HOME/go
,Windows的 %USERPROFILE%\go
(通常是 C:\Users\YourName\go
)。
如果想在不同的地方,可以使用 set GOPATH
指定目录的路径。(另一种通用的设置是GOPATH=$HOME).注意GOPATH一定不能是Go的安装目录。
go env
命令打印当前有效的GOPATH,如果没有设置则打印默认的位置。
为了方便,添加工作空间的 bin 目录到你的路径:
$ export PATH=$PATH:$(go env GOPATH)/bin
为了简短,接下来的文档使用 (go env GOPATH)。
导入路径(Import paths)
import path
是唯一的字符串表示包。包的导入路径对应工作空间里它的位置或者远程仓库位置。
标准库里的包具有简短的导入路径,比如 fmt
和 net/http
。对于你自己的包,指定的路径不能与标准库里的包或者其他内部包冲突。
如果你将代码保存在源文件仓库,那么应该使用源仓库的根目录作为你的基础路径。比如,如果你有 Github
账号,那么 github.com/{user}
就是你的基本路径。
注意不要再你能构建之前推送代码到远程仓库。
我们将使用 github.com/{user}
作为你的基础路径。在工作空间下创建一个目录保存源代码:
$ mkdir -p $GOPATH/src/github.com/user
第一个程序
要编译和运行一个简单的程序,先选择一个包路径(我们先用github.com/user/hello)并且在工作空间创建相应的包目录:
$ mkdir $GOPATH/src/github.com/user/hello
接下来,在这个目录下创建一个名为 hello.go
的文件,包含如下代码:
package main import "fmt" func main() { fmt.Println("Hello, world.") }
现在就可以构建并安装程序了:
$ go install github.com/user/hello
现在你就可以在你的系统里运行这个命令了。 go tool
通过GOPATH指定的工作空间查找 github.com/user/hello
包的源代码
如果已经在包目录里,就可以省略掉包路径
$ cd $GOPATH/src/github.com/user/hello $ go install
这个命令构建 hello
命令,产生一个可执行的binary。然后安装这个binary到工作空间下的 bin
目录,也就是 $HOME/go/bin/hello
go tool
只会在有错误的时候打印输出,所以如果没有内容产生,表示执行成功。
现在可以通过全路径运行程序
$ $GOPATH/bin/hello Hello, world.
第一个库
现在我们编写一个library并且在 hello
程序里使用。
同样,第一步先选择一个包路径(我们使用github.com/user/stringutil)先,创建包路径
$ mkdir $GOPATH/src/github.com/user/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) }
现在,使用 go build
测试包编译:
$ go build github.com/user/stringutil
如果已经在包源目录下,只需要:
go build
这不会产生输出文件。而是将编译完的包保存到本地构建缓存里。
现在修改 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
这一顿操作后,工作空间应该变成了:
bin/ hello # command executable src/ github.com/user/ hello/ hello.go # command source stringutil/ reverse.go # package source
Package names
Go源文件里的第一行一定是:
package name
其中name是包的默认名称。
(包中的所有文件必须使用相同的名称。)
Go的约定是报名是导入路径最后一个节点: crypto/rot13
的包名是 rot13
可执行命令的包名必须是 package main
。
不要求包名称在链接到单个二进制文件的所有包中都是唯一的,只要导入路径(它们的完整文件名)是唯一的。
测试
Go有一个由 go test
命令和测试包组成的轻量级测试框架。
创建一个用 _test.go
结尾的文件,里面的方法命名为 TestXXX
。测试框架会运行每个方法;如果方法调用失败方法比如 t.Error
或者 t.Fail
,测试就被认为失败了。
创建一个 $GOPATH/src/github.com/user/stringutil/reverse_test.go
文件测试 stringutil
:
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
:
$ go test github.com/user/stringutil ok github.com/user/stringutil 0.165s
远程包
导入路径可以描述如何使用诸如Git或Mercurial之类的修订控制系统来获取包源代码。go tool使用该属性自动从远程仓库拉去包。比如,本文档里的实例就保存在 github.com/golang/example
。如果你在包的导入路径引入远程URL, go get将会自动获取,构建并且安装它:
$ go get github.com/golang/example/hello $ $GOPATH/bin/hello Hello, Go examples!
如果工作空间不存在指定的包, go get
会将它放在GOPATH指定的第一个工作空间内。(如果包存在, go get
会跳过远程获取,就和 go install
的行为一样了)
经过上面的操作后,工作目录结构将会变为:
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
Gihub上托管的 hello
命令依赖同一仓库下的 stringutil
包。 hello.go
文件里的imports使用相同的导入路径规范,所以go get命令可以定位并且安装起来的包:
import "github.com/golang/exmaple/stringutil"
规范是最简单的方式让你的Go包可以对其他的可用
以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,也希望大家多多支持 码农网
猜你喜欢:- 从零开始编写一个库到 crates 中心
- 从零开始编写一个WEB服务器 - 基础
- Re从零开始的UI库编写生活之按钮
- Re从零开始的UI库编写生活之规范制定
- 从头开始编写任何机器学习算法的6个步骤:感知器案例研究
- [ Laravel从入门到精通系列 ] 测试系列 —— 从基于 PHPUnit 编写单元测试开始
本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。