内容简介:本文演示了一个简单的Go语言包的开发,以及请注意,这与其他编程环境不同,在这些环境中,每个项目都有一个单独的工作区,工作区与版本控制仓库紧密相关。
简介
本文演示了一个简单的 Go 语言包的开发,以及 go tool
命令的使用,包含:获取、构建、安装Go包和命令的标准方法。
go tool
要求用特别的方式来组织你的Go代码。仔细阅读本文,它解释了启动和运行Go安装的最简单方法。
代码组织
概述
- 程序员通常会将所有Go代码保存在一个工作区中
- 工作空间包含许多版本控制的仓库(repo)(例如,由Git管理的)
- 每个仓库包含一个或多个包
- 每个包由一个目录中的一个或多个Go源文件组成
- 包目录的路径确定其导入路径
请注意,这与其他编程环境不同,在这些环境中,每个项目都有一个单独的工作区,工作区与版本控制仓库紧密相关。
工作区
工作空间是一个目录层次结构,其根目录有两个目录:
src bin
go工具构建二进制文件并将其安装到 bin
目录。
src
子目录通常包含多个版本控制的仓库(例如Git),用于跟踪一个或多个源包的开发。
在实践中,工作区应该是什么样子呢? 下面给出一个例子:
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) ...
上面的这个树型结构展示出一个工作区包含了2个仓库( example
和 image
)。 example
仓库包含了2个命令( hello
和 outyet
)和一个库( stringutil
)。 image
仓库包含了 bmp
包和 一些其他的包。
通常工作区会包含很多的源仓库(包含需要多和命令)。大多数的Go开发者都会把他们的源代码和依赖存放在一个工作区。
命令和库是从不同类型的源包构建的。我们稍后会讨论这种区别。
GOPATH 环境变量
GOPATH
环境变量用来指定工作区的位置。默认是用户主目录的 go
目录,如在 Linux 和macOS上是 $HOME/go
, 在Windows上是 C:\Users\YourName\go
。
go env GOPATH
命令会打印出当前有效的 GOPATH
; 如果环境变量没有被设置会打印出默认的位置。
为方便起见,将工作空间的 bin
子目录添加到 PATH
:
$ export PATH=$PATH:$(go env GOPATH)/bin
为简洁起见,本文档其余部分中的脚本使用 $GOPATH
而不是 $(go env GOPATH)
。即
$ export PATH=$PATH:$GOPATH/bin
而如果还没有设置 $GOPATH
就运行写好的脚本,你需要替换为 $HOME/go
, 否则需要执行:
$ export GOPATH=$(go env GOPATH)
要学习更多关于gopath环境变量,可以使用查看帮助 go help gopath
要使用自定义的工作区,可以查看 https://golang.org/wiki/SettingGOPATH
导入路径
导入路径(import path)是唯一标识包的字符串。包的导入路径对应于其在工作空间内或远程仓库中的位置(如下所述)。
标准库中的包具有简短的导入路径,例如 fmt
和 net/http
。对于我们自己开发的包您必须选择一个基本路径,该路径不太可能与将来添加到标准库或其他外部库中发生冲突。
如果将代码保存在某个源仓库中,则应使用该源仓库的根作为基本路径。例如,如果你在 github.com/user
上有一个GitHub帐户,那么这应该是你的基本路径。
请注意,在构建代码之前,无需将代码发布到远程仓库。组织代码只是一个好习惯,好像有一天你会发布它一样。实际上,你可以选择任意路径名称,只要它对标准库和更大的Go生态系统是唯一的。
我们将使用 github.com/user
作为我们的基本路径。在工作区内创建一个目录,用于保存源代码:
$ mkdir -p $GOPATH/src/github.com/user
你的第一个Go程序
要编译和运行一个简单的程序,首先要选择一个包路径(我们会使用 github.com/user/hello
),然后在工作区里创建一个相应的包目录:
$ mkdir $GOPATH/src/github.com/user/hello
接下来,在hello目录里创建一个 hello.go
文件,写入以下内容:
package main import "fmt" func main() { fmt.Println("Hello, world.") }
现在就可以使用go工具来构建和安装该程序:
go install github.com/user/hello
注意,你可以在系统上的任何地方运行该命令。go工具通过在 GOPATH
指定的工作空间内查找 github.com/user/hello
包来查找源代码。
如果是在这个包目录内运行 go install
也可以忽略包路径:
$ cd $GOPATH/src/github.com/user/hello $ go install
该命令会生成一个 hello
命令,生成一个可执行的二进制文件。同时安装到工作区目录下的 bin
目录,生成的可执行文件是 hello
(如果是windows则是 hello.exe)。
在本例子中是 $GOPATH/bin/hello
, 也就是 $HOME/go/bin/hello
。
当有错误发生的时候,go工具仅会打印除错误,所以如果没有任何输出的时候说明已经执行成功。
可以通过全路径来运行:
$ $GOPATH/bin/hello Hello, world.
如果已经把 $GOPATH/bin
加入到了 PATH
, 可以直接输入二进制文件名:
$ hello Hello, world.
如果你正在使用一个版本控制系统,比如Git,现在是时候来初始化来生成一个仓库(repository),然后添加文件,做第一次提交。
当然这一步是可选的,不一定非要使用版本控制系统来写Go代码
$ cd $GOPATH/src/github.com/user/hello $ git init Initialized empty Git repository in /home/user/work/src/github.com/user/hello/.git/ $ git add hello.go $ git commit -m "initial commit" [master (root-commit) 0b4507d] initial commit 1 file changed, 1 insertion(+) create mode 100644 hello.go $ git push origin master
你的第一个库
我们再来写一个库,并在 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
如果已经在 github.com/user/stringutil
目录里,则直接执行:
$ go build
当然该命令不会生成文件,而是把编译好的包放到了本地的构建(build)缓存里。
确实 stringutil
包被编译后, 修改 hello.go
:
vim $GOPATH/src/github.com/user/hello
修改后的:
package main import ( "fmt" "github.com/user/stringutil" ) func main() { fmt.Println(stringutil.Reverse("!oG ,olleH")) }
再次安装
$ go install github.com/user/hello
执行:
$ hello Hello, Go!
通过上面的一些步骤后,现在我们的结构是这样子的:
bin/ hello # command executable src/ github.com/user/ hello/ hello.go # command source stringutil/ reverse.go # package source
包名
在Go原文件中第一个使用的语句必须是
package name
其中 name
就是包的默认名称。一个包中的所有文件必须使用相同的包名。
Go的约定是包名称是导入路径的最后一个元素,例如导入的包 crypto/rot13
, 包名就是 rot13
如果是可执行的文件,包名必须使用 main
。
不强制要求所有的包名都是唯一的,但是要求导入的路径必须是唯一的(全路径文件名)。
更多关于go的命名规范可以查看 Effective Go
测试
Go提供了一个由 go test
和 testing
包组成的测试框架。
通过创建一个以 _test.go
结尾的文件,里面写有以 TestXXX
开头的函数。测试框架会运行每一个这样的函数,如果函数调用了一个失败的函数,如 t.Error
或 t.Error
, 那么测试就算不通过。
通过添加一个测试文件到 stringutil
包中,
$ vim $GOPATH/src/github.com/user/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
:
$ go test github.com/user/stringutil ok github.com/user/stringutil 0.165s
如果当前是在 go test github.com/user/stringutil
目录中,则直接执行:
$ go test ok github.com/user/stringutil 0.165s
更多细节可以运行 go run test 和 查看 测试包文档
远程包
导入路径可以描述如何使用诸如Git之类的版本控制系统来获取包源代码。go工具使用此属性自动从远程仓库获取包。例如,本文档中描述的示例也保存在GitHub github.com/golang/example
上托管的Git仓库中。如果你在包的导入路径中包含仓库URL,那么go将自动获取,构建和安装它:
$ go get github.com/golang/example/hello $ $GOPATH/bin/hello Hello, Go examples!
如果指定的包不在工作区, go get
将会通过 GOPATH
把它放到指定的工作区,如果包已经存在, go get
会跳过远程获取,其行为与 go install
相同。
上面 go get
之后的目录结构如下:
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
在GitHub上托管的 hello
命令取决于同一仓库中的 stringutil
包。 hello.go
文件中的导入使用相同的导入路径约定,因此 go get
命令也能够找到并安装依赖包。
import "github.com/golang/example/stringutil"
此约定是使你的Go包可供其他人使用的最简单方法。
Go Wiki 和 godoc.org 提供了外部Go项目的列表。
有关使用go工具使用远程仓库的更多信息, 可以查看 go help importpath
以上所述就是小编给大家介绍的《如何编写Go代码》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 码农网 的支持!
猜你喜欢:本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
科学的极致:漫谈人工智能
集智俱乐部 / 人民邮电出版社 / 2015-7 / 49.00元
集智俱乐部是一个从事学术研究、享受科学乐趣的探索者组成的团体,倡导以平等开放的态度、科学实证的精神进行跨学科的研究与交流,力图搭建一个中国的“没有围墙的研究所”。这些令人崇敬的、充满激情与梦想的集智俱乐部成员将带你了解图灵机模型、冯•诺依曼计算机体系结构、怪圈与哥德尔定理、通用人工智能、深度学习、人类计算与自然语言处理,与你一起展开一场令人热血沸腾的科学之旅。一起来看看 《科学的极致:漫谈人工智能》 这本书的介绍吧!