内容简介:本文演示了一个简单的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代码》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 码农网 的支持!
猜你喜欢:本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
Python Algorithms
Magnus Lie Hetland / Apress / 2010-11-24 / USD 49.99
Python Algorithms explains the Python approach to algorithm analysis and design. Written by Magnus Lie Hetland, author of Beginning Python, this book is sharply focused on classical algorithms, but it......一起来看看 《Python Algorithms》 这本书的介绍吧!